---
title: Internacionalização
description: >-
  Sirva sua documentação em vários idiomas com roteamento sensível ao locale, navegação por idioma, interface traduzida e SEO — tudo baseado em convenções.
---

O Blume serve um projeto em muitos idiomas. Coloque os arquivos traduzidos no lugar certo e o Blume cuida do roteamento, do seletor de idiomas, da navegação por locale e do SEO para você — não há uma camada de roteamento separada para manter. É opcional: sem um bloco `i18n`, seu site continua em um único idioma exatamente como antes. Também se combina com o [versionamento](/pt/docs/content/versioning) — um snapshot congelado mantém suas traduções, e o fallback de locale funciona dentro de cada versão.

## Ative o recurso [#enable-it]

Adicione um bloco `i18n` listando seus locales e qual deles é o padrão:

```ts blume.config.ts lineNumbers
i18n: {
  defaultLocale: "en",
  locales: [
    { code: "en", label: "English" },
    { code: "fr", label: "Français" },
    { code: "ar", label: "العربية", dir: "rtl" },
  ],
}
```

Cada locale tem um `code` (usado nas URLs), um `label` (exibido no seletor de idiomas) e um `dir` opcional para escritas da direita para a esquerda (`"ltr"` por padrão). Um `style` opcional dá ao [`blume translate`](/pt/docs/cli/translate) orientações livres para o locale — registro, dialeto, terminologia, por exemplo `"Brazilian Portuguese, informal você"` — de modo que a escolha fica fixada desde a primeira tradução, em vez de ser decidida pelo agente.

## Organize o conteúdo traduzido [#organize-translated-content]

O locale padrão fica na raiz do seu conteúdo. Todos os outros locales são pastas de nível superior nomeadas pelo respectivo `code`, espelhando a estrutura padrão:

```txt
docs/
  index.mdx               ->  /
  guides/quickstart.mdx   ->  /guides/quickstart
  fr/
    index.mdx             ->  /fr
    guides/quickstart.mdx ->  /fr/guides/quickstart
  ar/
    index.mdx             ->  /ar
```

| Arquivo                         | Rota                    |
| ------------------------------- | ----------------------- |
| `docs/index.mdx`                | `/`                     |
| `docs/guides/quickstart.mdx`    | `/guides/quickstart`    |
| `docs/fr/guides/quickstart.mdx` | `/fr/guides/quickstart` |

Não dê ao locale padrão uma pasta própria: apenas os outros códigos são pastas de locale, então `docs/en/` com `en` como padrão é conteúdo comum, publicado em `/en/…` (e em `/fr/en/…` como fallback em francês). O Blume emite um aviso quando encontra uma pasta assim.

Você traduz apenas os arquivos que quiser — todo o resto recorre automaticamente ao fallback (veja [Fallbacks](#fallbacks)).

### Sufixos de nome de arquivo [#filename-suffixes]

Prefere manter as traduções ao lado do original? Defina `parser: "dot"` e nomeie os arquivos com um sufixo de locale em vez de usar pastas:

```txt
docs/
  guides/quickstart.mdx     ->  /guides/quickstart      (default)
  guides/quickstart.fr.mdx  ->  /fr/guides/quickstart   (French)
```

Bom para traduções esparsas — coloque as poucas páginas que você traduziu junto às originais sem espelhar a árvore inteira.

### Arquivos compartilhados [#shared-files]

Para conteúdo que é igual em todos os idiomas — um changelog, uma página de status — adicione um marcador `$` para que um único arquivo sirva a todos os locales sem duplicação:

```txt
docs/changelog.$.mdx   ->  /changelog and /fr/changelog (same content)
docs/guides/meta.$.ts   (folder meta applied to every locale)
```

Um `meta.ts` específico de um locale ainda substitui o compartilhado para aquele idioma.

## URLs do locale padrão [#default-locale-urls]

Por padrão, o locale padrão não tem prefixo de URL (`/`, `/guides/quickstart`), enquanto os outros locales são prefixados (`/fr/…`). Isso mantém limpas as URLs do seu idioma principal. Para prefixar todos os locales, incluindo o padrão:

```ts blume.config.ts lineNumbers
i18n: {
  // …
  hideDefaultLocalePrefix: false, // /en/…, /fr/…
}
```

## Navegação por locale [#per-locale-navigation]

Cada idioma ganha sua própria barra lateral, construída a partir dos arquivos daquele locale — então as traduções podem divergir em estrutura, ordenação ou rótulos. Os arquivos [`meta.ts`](/pt/docs/content/meta) de pasta também são resolvidos por locale: com o parser `dir` padrão, coloque um `meta.ts` em `fr/guides/` para ordenar o grupo em francês de forma independente. Até que um locale tenha o seu (ou um `meta.$.ts` compartilhado), o grupo dele espelha o do locale de [fallback](#fallbacks) — o `meta.ts` daquela pasta e o `sidebar.display` definido pela página de índice dela —, de modo que as páginas que recorrem ao fallback mantêm os mesmos títulos, a mesma ordem e os mesmos grupos recolhíveis. Com o parser `dot`, as traduções ficam ao lado das originais, portanto o `meta.ts` de uma pasta se aplica a todos os locales. Todo o resto da [navegação](/pt/docs/content/navigation) funciona da mesma forma, por idioma.

As abas do cabeçalho, os links do cabeçalho e o rodapé são configurados, e não derivados do conteúdo, então seus rótulos são localizados em `blume.config.ts`. Todo rótulo configurado aceita um mapa por locale (`{ en: "Docs", fr: "Documentation" }`) além da forma de string simples, recorrendo à entrada do locale padrão para os locales que você não preencheu: rótulos de abas e de menus suspensos ([Abas](/pt/docs/content/navigation#tabs)), [links em destaque](/pt/docs/content/navigation#featured-links), [ações do cabeçalho](/pt/docs/content/navigation#header-actions) e a chamada para ação, links do [rodapé](/pt/docs/configuration#footer), o texto do [banner](/pt/docs/configuration#banner) e do link dele, e os clientes personalizados do menu [Conectar ao MCP](/pt/docs/discoverability/mcp#connect-to-mcp-menu).

```ts blume.config.ts lineNumbers
navigation: {
  cta: {
    href: "https://acme.dev/signup",
    label: { en: "Start free", fr: "Essai gratuit" },
  },
},
footer: {
  links: [
    { label: { en: "Pricing", fr: "Tarifs" }, href: "https://acme.dev/pricing" },
  ],
},
```

Os caminhos das abas, os links do cabeçalho e do rodapé e o link do logo do cabeçalho também passam para o locale do leitor sempre que esse locale serve a rota, de modo que os elementos da interface permanecem dentro de um único idioma. Uma rota servida apenas pelo locale padrão — uma [página personalizada](/pt/docs/advanced/custom-pages) ou o índice gerado do [changelog](/pt/docs/advanced/changelog) — mantém o próprio caminho em vez de apontar para uma URL localizada que daria 404.

## Fallbacks

Quando uma página ainda não foi traduzida, o Blume renderiza o conteúdo do locale de fallback na URL localizada — assim o link funciona, a página é totalmente pré-renderizada e os motores de busca não são levados a um beco sem saída. O fallback usa por padrão o seu `defaultLocale`:

```ts blume.config.ts lineNumbers
i18n: {
  // …
  fallbackLocale: "en", // default; set to null to 404 instead
}
```

Páginas de fallback apontam o link canônico para a página que copiam, são excluídas do índice de busca, do `llms.txt` e das listas de páginas do MCP e da API JSON, e não são anunciadas como traduções reais no `hreflang`, de modo que conteúdo não traduzido não concorre por posicionamento. Elas ainda aparecem na barra lateral daquele locale, então a navegação permanece completa — um leitor consegue chegar a qualquer página em qualquer idioma.

As notas de versão de uma fonte [`githubReleases()`](/pt/docs/content/sources/github-releases) são a exceção: elas são publicadas em um único idioma, então nunca são copiadas para as URLs de outros locales e não exibem seletor de idiomas.

:::tip
Comece traduzindo suas páginas mais importantes — a página inicial, o guia rápido e os principais guias — e deixe o resto usar o fallback. Você pode preencher as traduções ao longo do tempo sem quebrar nenhum link.
:::

## Links entre locales [#links-across-locales]

Escreva os links internos como você faria no locale padrão — `[Setup](/guides/setup)`, `<Card href="/guides/setup">` — em todos os idiomas, inclusive nas páginas traduzidas. Quando uma página é renderizada sob um prefixo de locale, o Blume move cada link de página relativo à raiz para aquele locale (`/fr/guides/setup`), desde que a rota seja servida ali, como uma tradução real ou como página de fallback. Um link sem variante por locale — uma página personalizada, uma rota gerada ou uma tradução ausente em um site com fallbacks desativados — mantém o destino que você escreveu em vez de apontar para um 404, e um link que já carrega um prefixo de locale (`/de/guides/setup`) fica intocado, de modo que os links entre locales permanecem explícitos.

As âncoras acompanham o link, então os ids dos títulos precisam coincidir entre os idiomas. O [`blume translate`](/pt/docs/cli/translate) cuida disso: cada título traduzido é fixado ao id do título de origem com um marcador `[#id]` no final. Em uma tradução que você escreve à mão, fixe os títulos você mesmo com o mesmo [marcador `[#custom-id]`](/pt/docs/content/syntax#custom-anchors) — caso contrário, `#ordering` não vai corresponder ao `#ordre` gerado automaticamente na página em francês, e o `blume validate` reporta a divergência na página traduzida em que o leitor de fato cai.

## Traduzindo com um agente [#translating-with-an-agent]

Você não precisa preencher os locales manualmente. O [`blume translate`](/pt/docs/cli/translate) encontra todas as páginas que estão faltando ou desatualizadas em cada locale e as traduz com uma CLI de agente local ([Codex](https://developers.openai.com/codex/cli) ou [Claude Code](https://claude.com/claude-code)):

```bash
blume translate --codex
```

O Blume valida a estrutura de cada resultado — frontmatter, blocos de código, links — e escreve os arquivos ele mesmo; o agente apenas traduz o texto. Um registro versionado (`blume.translations.json`) rastreia de qual revisão de origem cada tradução veio, então as reexecuções tocam apenas o que mudou, e as traduções que você escreveu à mão são adotadas como estão, nunca sobrescritas. Em CI, `blume translate --check` falha quando uma página de origem avançou além de suas traduções.

## O seletor de idiomas [#the-language-switcher]

Quando a i18n está ativada, um seletor de idiomas aparece automaticamente no cabeçalho, gerado a partir dos seus `locales`. Para cada página, ele aponta para a tradução correspondente em todos os idiomas; onde falta uma tradução, ele aponta para a página de fallback e a marca como não traduzida. Com os fallbacks desativados (`fallbackLocale: null`), não há página para a qual apontar, então o seletor deixa esse idioma de fora. Não há nada para configurar. Páginas de uma fonte [GitHub Releases](/pt/docs/content/sources/github-releases) são a exceção: as notas de versão existem em um único idioma, então essas páginas são renderizadas sem seletor.

## Roteamento pelo idioma do navegador [#routing-by-browser-language]

Para enviar os visitantes para o próprio idioma deles, ative o `routeByBrowserLanguage`:

```ts blume.config.ts lineNumbers
i18n: {
  defaultLocale: "en",
  locales: [
    { code: "en", label: "English" },
    { code: "fr", label: "Français" },
  ],
  routeByBrowserLanguage: true,
}
```

Um visitante que chega de fora do site à página inicial do idioma padrão é então levado à página inicial no idioma preferido do navegador dele, quando o site tem esse idioma. O Blume tenta cada idioma que o navegador prefere, em ordem, buscando primeiro uma correspondência exata de código e depois o idioma base (`fr-CA` encontra `fr`). Se o idioma padrão vier primeiro, o visitante permanece onde está. Depois que um leitor escolhe um idioma com o seletor, o Blume lembra a escolha e deixa de redirecioná-lo. Só a página inicial é redirecionada; um link para qualquer outra página abre exatamente como foi escrito.

O redirecionamento acontece no navegador antes de a página ser exibida, então funciona em qualquer host, inclusive em builds estáticos. Ele vem desativado por padrão porque os motores de busca rastreiam em um único idioma: com ele ativado, mantenha as [alternativas `hreflang`](#seo) que o Blume emite para que as páginas de cada idioma continuem sendo indexadas.

## Interface traduzida [#translated-ui]

O Blume inclui traduções nativas para os elementos da própria interface — “Nesta página”, “Buscar”, “Editar no GitHub” e o restante — de modo que um locale com um pacote nativo já vem com a interface traduzida. **Você traduz apenas o seu conteúdo.**

Há pacotes para mais de 30 idiomas — árabe, bengali, búlgaro, catalão, chinês (simplificado e tradicional), croata, tcheco, dinamarquês, holandês, finlandês, francês, alemão, grego, hebraico, híndi, húngaro, indonésio, italiano, japonês, coreano, norueguês, persa, polonês, português (e português brasileiro), romeno, russo, sérvio, eslovaco, espanhol, sueco, tailandês, turco, ucraniano e vietnamita. Eles são mantidos pela comunidade — abra um PR para adicionar um locale ou aprimorar uma tradução.

Strings ausentes ou não incluídas recorrem ao locale padrão e, depois, ao inglês. Para substituir uma string ou fornecer seu próprio idioma, defina `i18n.ui`, com chaves por locale:

```ts blume.config.ts lineNumbers
i18n: {
  // …
  ui: {
    fr: {
      search: { button: "Rechercher", placeholder: "Rechercher…" },
      page: { previous: "Précédent", next: "Suivant" },
    },
  },
}
```

## SEO

O SEO localizado é cuidado para você — não há metadados por página para escrever:

- `<html lang>` e `dir` são definidos a partir do locale ativo.
- As alternativas `hreflang` apontam para todas as traduções reais de uma página que os motores de busca podem indexar (uma tradução com `noindex`, oculta ou com canonical apontando para outro lugar fica de fora), mais um `x-default` apontando para o locale padrão.
- As URLs canônicas são corretas por locale, e o JSON-LD carrega `inLanguage`.

Defina [`deployment.site`](/pt/docs/deployment) para que isso possa ser emitido como URLs absolutas.

## Busca [#search]

A busca é limitada ao idioma ativo: em uma página `/fr/…`, o diálogo retorna resultados em francês, com uma opção **Todos os idiomas** para buscar em todos os locales de uma vez. Os índices padrão (Orama) e FlexSearch filtram no navegador, o Pagefind mantém um índice por idioma, e o Algolia, o Orama Cloud e o Typesense carregam um campo `locale` em cada registro. O Mixedbread não consegue limitar a busca por idioma, então com ele toda busca abrange todos os locales e o diálogo não exibe essa opção. Veja [Busca](/pt/docs/configuration/search) para saber como cada adaptador lida com isso.

## Da direita para a esquerda [#right-to-left]

Defina `dir: "rtl"` em um locale e o Blume espelha toda a interface — a barra lateral, o cabeçalho, o índice da página, a paginação, a busca e os menus — e define `<html dir>` de acordo. Duas coisas permanecem deliberadamente da esquerda para a direita: **blocos de código** (código se lê da esquerda para a direita em qualquer idioma) e **conteúdo de fallback** — uma página não traduzida mantém a direção do idioma em que ela realmente está escrita, então o inglês exibido sob um locale RTL continua legível enquanto os elementos ao redor são espelhados.

## Para onde ir agora [#where-to-next]

**[Navegação](/pt/docs/content/navigation)**

Molde a barra lateral, a ordenação e as abas de cada locale.

**[Descoberta](/pt/docs/discoverability)**

Sitemaps, Open Graph e dados estruturados.
