Busca
Busca do lado do cliente que funciona imediatamente, sem chaves de API, além de backends hospedados e semânticos opcionais para os quais você pode migrar conforme sua documentação cresce.
O Blume inclui busca local sem infraestrutura hospedada e sem chaves de API. Ela roda no navegador, funciona tanto em blume dev quanto em blume build e indexa apenas o seu conteúdo real — elementos de navegação e páginas excluídas são ignorados. Quando ela deixar de ser suficiente, você pode migrar para um backend hospedado ou semântico sem mudar a aparência ou o comportamento da busca — só muda o search.provider que você configura.
O Blume alcança paridade com o conjunto de provedores do Fumadocs: Orama, FlexSearch, Algolia, Orama Cloud, Typesense e Mixedbread (além do Pagefind). Somente o SDK do provedor configurado é instalado no seu projeto, então escolher um backend nunca traz os outros junto.
Usando a busca
Abra a busca com ⌘K (ou Ctrl K), ou pressione / quando não estiver digitando em um campo. Esc a fecha, e ⌘J (ou Ctrl J) alterna o painel de pré-visualização de resultados.
As consultas correspondem a títulos, descrições e texto do corpo das páginas, com as correspondências de título classificadas em primeiro lugar e as descrições acima do corpo.
Páginas populares
Antes de o leitor digitar uma consulta, o diálogo de busca exibe uma lista Popular. Por padrão, são as seis primeiras páginas da barra lateral — o que, em sites com várias abas, muitas vezes destaca a seção errada. Em vez disso, fixe os links que você quiser:
search: {
popular: [
{ href: "/guides/getting-started", icon: "rocket", label: "Getting started" },
{ href: "/guides/install", icon: "download", label: "Install" },
{ href: "/concepts/overview", label: "Overview" },
],
},
Cada entrada recebe um href (rota interna ou URL externa) e um label, além de um icon opcional — o nome de um ícone integrado, um caminho ou URL de imagem, ou um SVG inline (as mesmas entradas dos ícones de navegação), com um glifo de arquivo como padrão. Omita popular ou deixe a lista vazia para manter o comportamento padrão baseado na barra lateral.
Escreva o href como se o site estivesse montado na raiz — um basePath é aplicado automaticamente, igual em navigation.featured. URLs externas passam sem alteração.
O que é indexado
Para Orama, FlexSearch, Algolia, Orama Cloud e Typesense — e para a ferramenta search_docs do servidor MCP —, o Blume indexa o título, a descrição e o corpo de cada página reduzido a texto simples: blocos de código, imagens e marcação são removidos, para que os resultados permaneçam relevantes. Esses índices são construídos a partir dos seus arquivos-fonte, então são idênticos em desenvolvimento e em produção. Já o Pagefind indexa o HTML compilado, e o Mixedbread sincroniza seu Markdown bruto, então ambos sempre buscam no código.
Se a sua documentação depende de exemplos de código para termos pesquisáveis como opções, métodos ou nomes de erros, ative os blocos de código cercados nos índices construídos a partir da fonte:
search: {
indexing: {
includeCodeBlocks: true,
},
},
O corpo e o título de cada bloco cercado (blume.config.ts, acima) se tornam pesquisáveis; a linguagem e os marcadores do bloco, não. Em páginas .mdx, o índice lê os componentes como o texto que eles exibem — o título de um Card, o rótulo de uma Tab, as descrições de uma TypeTable — usando os mesmos serializadores das superfícies de agente, então uma entrada em ai.markdownComponents cobre também os seus próprios componentes. A opção não tem efeito no Pagefind nem no Mixedbread. Espere que o índice cresça junto com o conteúdo cercado — o índice do cliente é enviado a todos os leitores, os provedores hospedados limitam o tamanho do registro (o Algolia rejeita o lote de sincronização quando o registro de uma página excede o limite do seu plano, mantendo o índice anterior no ar) e uma correspondência dentro de um bloco cercado exibe o código achatado no trecho do resultado.
Em um site com versionamento, os resultados ficam restritos por padrão à versão que está sendo visualizada, com um botão “Todas as versões” no rodapé do diálogo (memorizado por leitor). As correspondências de outras versões indicam sua versão na linha. Orama, FlexSearch, Algolia e Typesense respeitam esse escopo — os registros hospedados carregam uma faceta version, com a documentação atual enviada como "current" — enquanto o Pagefind permanece sem escopo, seguindo o mesmo comportamento que tem com idiomas.
Tags
Adicione search.tags ao frontmatter de uma página para agrupá-la sob um filtro no diálogo de busca — os leitores podem restringir os resultados a uma tag com um clique. As tags também se tornam uma faceta nos provedores hospedados.
search:
tags: [api, reference]
Provedores
Os provedores do lado do cliente dispensam chaves e não precisam de configuração extra. Os hospedados recebem credenciais públicas em blume.config.ts (seguras para enviar ao navegador) e leem sua chave de administração secreta de uma variável de ambiente no momento do build — o segredo nunca chega à configuração nem ao bundle do cliente.
Orama (padrão)
O mecanismo padrão do Blume. Ele constrói um índice JSON servido em /blume-search.json e o consulta no navegador — instantâneo, do lado do cliente e ativo em blume dev enquanto você edita. Sem chaves, sem serviço.
search: {
provider: "orama", // default
}
Escritas não latinas
O tokenizador padrão do Orama mantém apenas letras latinas básicas, dígitos e um punhado de vogais acentuadas, então textos em qualquer outra escrita — japonês, chinês, coreano e tailandês, mas igualmente russo, grego, hebraico e híndi — não produziriam nenhuma correspondência. O Blume cuida disso para você: quando i18n.defaultLocale corresponde a uma escrita não latina, o índice passa a usar um tokenizador que segmenta palavras (baseado no Intl.Segmenter, nativo do navegador e do Node). Basta declarar o idioma do seu site:
i18n: {
defaultLocale: "ja",
locales: [{ code: "ja", label: "日本語" }],
}
O mesmo tokenizador atende o diálogo de busca, a ferramenta search_docs do servidor MCP e o embasamento do Ask AI. Quem decide é a escrita, não o nome do idioma — az-Cyrl é segmentado, enquanto sr-Latn não é — e é o idioma padrão que decide por todo o índice: em um site com vários idiomas, todas as páginas compartilham o tokenizador do idioma padrão. Com um padrão não latino, isso é seguro, porque as palavras latinas sobrevivem intactas à segmentação, então páginas em inglês permanecem pesquisáveis ao lado do idioma padrão. O contrário não vale: traduções não latinas em um site com padrão latino não são pesquisáveis. Idiomas de escrita latina que dependem bastante de diacríticos (vietnamita, ou sérvio em escrita latina) também se saem pior no tokenizador padrão, que normaliza apenas algumas vogais acentuadas e divide as palavras no restante.
Japonês e chinês vão um passo além. A segmentação sozinha indexa um termo composto como suas partes — 資金決済法 como 資金, 決済 e 法 — o que permite que uma página que mencione cada parte em algum lugar seja melhor classificada do que a página que realmente trata do termo. Por isso, Han, Hiragana e Katakana são indexados como pares de caracteres sobrepostos, e as consultas sobre esses índices preferem páginas que contenham os pares de um termo juntos, afrouxando para a correspondência de qualquer par quando nenhuma página os contém todos, de modo que digitar uma frase inteira ainda retorna as páginas mais próximas. Coreano e tailandês mantêm suas palavras segmentadas.
FlexSearch
Uma segunda opção do lado do cliente e sem chaves. Ela reutiliza o mesmo índice /blume-search.json que o Orama gera e constrói um índice de documentos do FlexSearch no navegador. Funciona em blume dev e blume build.
O FlexSearch não tem um mecanismo equivalente de segmentação, então, para sites em escritas não latinas, prefira o Orama (o padrão) ou o Pagefind, cujo binário pagefind_extended indexa um conjunto amplo de idiomas e segmenta chinês, japonês e coreano nativamente.
search: {
provider: "flexsearch",
}
Pagefind
Para documentações muito grandes, opte pelo Pagefind. Ele indexa o HTML compilado e carrega o índice em fragmentos sob demanda, mantendo a carga inicial mínima por maior que o site fique.
search: {
provider: "pagefind",
}
O Pagefind só é executado durante o blume build, então a busca não fica disponível em blume dev com esse provedor.
Algolia
O navegador consulta o Algolia diretamente com sua chave somente de busca. Cada blume build substitui o índice usando a chave de administração de ALGOLIA_ADMIN_API_KEY (o build emite um aviso e pula o envio se ela não estiver definida). Todo o índice é substituído a cada sincronização, então páginas que você excluir ou renomear não permanecem como resultados desatualizados.
search: {
provider: "algolia",
algolia: {
appId: "YOUR_APP_ID",
indexName: "docs",
searchApiKey: "YOUR_SEARCH_ONLY_KEY", // public
},
}
Orama Cloud
Orama hospedado. O navegador consulta o endpoint do seu índice com a chave de API pública; o blume build envia registros para o índice usando ORAMA_PRIVATE_API_KEY. Defina indexId para habilitar a sincronização.
search: {
provider: "orama-cloud",
oramaCloud: {
endpoint: "https://cloud.orama.run/v1/indexes/your-index",
apiKey: "YOUR_PUBLIC_API_KEY",
indexId: "your-index-id", // for the build-time sync
},
}
Typesense
Typesense auto-hospedado ou na nuvem. O navegador consulta a coleção com a chave somente de busca; o blume build recria a coleção e importa os documentos usando TYPESENSE_ADMIN_API_KEY. A coleção é descartada e reconstruída a cada sincronização, para que páginas excluídas ou renomeadas não permaneçam como resultados desatualizados — se você ajustar manualmente as configurações da coleção, reaplique-as após um build.
search: {
provider: "typesense",
typesense: {
host: "xyz.a1.typesense.net",
collection: "docs",
searchApiKey: "YOUR_SEARCH_ONLY_KEY", // public
// port + protocol default to 443 / https
},
}
Mixedbread
Busca semântica via Mixedbread. As consultas passam por um endpoint /api/search gerado que guarda sua chave, então esse provedor exige saída de servidor (deployment.output: "server"). O endpoint lê MIXEDBREAD_API_KEY. Sincronize seu conteúdo com o store usando a CLI do Mixedbread no seu build, por exemplo, mxbai vs sync <STORE_ID> ./content --ci.
search: {
provider: "mixedbread",
mixedbread: {
storeId: "YOUR_STORE_ID",
},
}
Desativando a busca
search: {
provider: "none",
}
Excluindo páginas
Apenas as páginas indexáveis são pesquisadas. Uma página fica de fora do índice quando define search.exclude no frontmatter:
search:
exclude: true
Páginas ocultas também são excluídas por padrão. Para indexá-las mesmo assim, ative explicitamente:
search: {
indexing: { includeHiddenPages: true },
}