---
title: Busca
description: >-
  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 [#using-search]

Abra a busca com <Badge variant="accent">⌘K</Badge> (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 [#popular-pages]

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:

```ts blume.config.ts lineNumbers
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](/docs/content/components#icon), 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.

> **Warning**
>
> Uma lista curada é um único conjunto de links compartilhado por todos os
> idiomas. Em um site com `i18n` configurado, o comportamento padrão da barra
> lateral segue o idioma do leitor, mas as entradas de `popular` apontam para
> onde o `href` indicar — então fixe rotas com prefixo de idioma apenas se
> quiser que todos os leitores sejam levados àquele idioma.

## O que é indexado [#whats-indexed]

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:

```ts blume.config.ts lineNumbers
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](/docs/discoverability/markdown), 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](/docs/content/versioning), 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.

```yaml
search:
  tags: [api, reference]
```

## Provedores [#providers]

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) [#orama-default]

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.

```ts blume.config.ts lineNumbers
search: {
  provider: "orama", // default
}
```

#### Escritas não latinas [#non-latin-scripts]

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`](/docs/content/i18n) 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:

```ts blume.config.ts lineNumbers
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](https://github.com/nextapps-de/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](#pagefind), cujo binário `pagefind_extended` indexa um conjunto amplo de idiomas e segmenta chinês, japonês e coreano nativamente.

```ts blume.config.ts lineNumbers
search: {
  provider: "flexsearch",
}
```

### Pagefind

Para documentações muito grandes, opte pelo [Pagefind](https://pagefind.app). 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.

```ts blume.config.ts lineNumbers
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](https://www.algolia.com) 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.

```ts blume.config.ts lineNumbers
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.

```ts blume.config.ts lineNumbers
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](https://typesense.org) 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.

```ts blume.config.ts lineNumbers
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](https://www.mixedbread.com). 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`.

```ts blume.config.ts lineNumbers
search: {
  provider: "mixedbread",
  mixedbread: {
    storeId: "YOUR_STORE_ID",
  },
}
```

### Desativando a busca [#disabling-search]

```ts blume.config.ts lineNumbers
search: {
  provider: "none",
}
```

## Excluindo páginas [#excluding-pages]

Apenas as páginas indexáveis são pesquisadas. Uma página fica de fora do índice quando define `search.exclude` no frontmatter:

```yaml
search:
  exclude: true
```

[Páginas ocultas](/docs/content/navigation#hidden-pages) também são excluídas por padrão. Para indexá-las mesmo assim, ative explicitamente:

```ts blume.config.ts lineNumbers
search: {
  indexing: { includeHiddenPages: true },
}
```
