Faça sua pergunta e obtenha um resumo do documento referenciando esta página e o provedor AI de sua escolha
Histórico de versões
- "Versão inicial"v9.5.1026/09/2026
O conteúdo desta página foi traduzido com uma IA.
Veja a última versão do conteúdo original em inglêsSe você tiver uma ideia para melhorar esta documentação, sinta-se à vontade para contribuir enviando uma pull request no GitHub.
Link do GitHub para a documentaçãoCopiar o Markdown do documento para a área de transferência
Como internacionalizar sua aplicação TanStack Start usando Paraglide JS em 2026
Sumário
O que é o Paraglide JS?
O Paraglide JS (criado pela inlang) é uma biblioteca de i18n baseada em compilador. Em vez de enviar um runtime que busca chaves em um objeto JSON, ele compila cada mensagem em uma função JavaScript tipada (m.about_title()). Mensagens não utilizadas podem ser removidas pelo empacotador (bundler), e um erro de digitação em uma chave resulta em um erro de compilação.
O Paraglide é a abordagem de i18n utilizada nos exemplos oficiais do TanStack Router, integrando-se ao TanStack Start através de três partes:
- um plugin Vite que compila mensagens e o runtime em
src/paraglide; - um middleware de servidor que resolve o idioma (locale) de cada requisição;
- uma reescrita de roteador (router rewrite) que mapeia URLs localizadas (
/fr/about) para sua árvore de rotas (/about), eliminando a necessidade de um segmento$locale.
Este guia configura todas essas três etapas e, em seguida, aborda tudo o que o Paraglide deixa a seu critério: lang e dir, seletor de idioma, metadados traduzidos, canonical, hreflang com x-default, Open Graph, JSON-LD, sitemap, robots.txt, pré-renderização e páginas 404 localizadas.
Procurando por outra stack? Consulte o guia TanStack Start + use-intl, o guia TanStack Start + Lingui ou o guia TanStack Start + Intlayer.
Comparando as duas abordagens baseadas em compilador? Leia o Intlayer é mais leve que o Paraglide?.
O que o benchmark diz sobre o Paraglide no TanStack Start
O benchmark de i18n executa a mesma aplicação TanStack Start de 10 páginas e 10 idiomas com todas as principais bibliotecas e mede o que o navegador realmente baixa.
Carregamento JSON dinâmico
Carrega as traduções tardiamente em tempo de execução
JSON com escopo (namespacing)
Namespaces de tradução por página
Benchmark de Desempenho I18n
O que é essa métrica?
O tamanho total compactado em gzip do pacote da biblioteca de internacionalização. Inclui apenas o provedor e a lógica de recuperação de conteúdo após o tree-shaking e a minificação.
Por que é importante?
Um tamanho de biblioteca menor reduz a carga útil inicial de JavaScript, resultando em tempos de download e execução mais rápidos no cliente.
Ver como
Principais números para @inlang/paraglide-js@2.15.1, medidos em 26/09/2026 (gzip):
Abrir a tabela em um modal para ver todo o conteúdo claramente
| Configuração | Tamanho da biblioteca | JS por página | Vazamento de outros idiomas | Vazamento de outras páginas | Carregamento da página |
|---|---|---|---|---|---|
| Sem i18n (app base) | - | 111.0 KB | 0% | 0% | 15.7 ms |
| Paraglide JS | 1.8 KB | 125.1 KB | 49.7% | 0% | 22.1 ms |
react-intlayer | 4.5 KB | 126.8 KB | 0% | 0% | 14.8 ms |
use-intl | 75.9 KB | 128.7 KB | 0% | 0% | 17.4 ms |
| Lingui | 56.7 KB | 120.2 KB | 8.6% | 0% | 21.9 ms |
O que observar:
- O runtime é minúsculo e não há vazamento de páginas. O runtime é gerado para a sua configuração e as mensagens são importadas apenas onde são utilizadas.
- Há vazamento de idiomas. Cada função de mensagem contém todos os idiomas, de modo que cerca de metade das strings traduzidas enviadas para uma página pertencem a idiomas que o visitante não utiliza. Quanto mais idiomas você adicionar, maior se tornará essa proporção.
- O carregamento da página é o mais lento do grupo, em parte porque o idioma é resolvido por meio de estratégias a cada chamada, em vez de ser lido a partir de um contexto React.
Veja os dados completos: Relatório de benchmark do TanStack Start e o repositório do benchmark.
Comparação de recursos no TanStack Start
Como o Paraglide JS se compara com as outras bibliotecas comumente usadas no TanStack Start:
Abrir a tabela em um modal para ver todo o conteúdo claramente
| Recurso | react-intlayer (Intlayer) | use-intl | Paraglide JS | Lingui |
|---|---|---|---|---|
| Traduções próximas aos componentes | ✅ Co-localizado | ❌ JSON centralizado | ❌ Um arquivo JSON por idioma | ⚠️ Texto de origem nos comp. |
| Integração com TypeScript | ✅ Tipos gerados automaticamente | ✅ Via AppConfig | ✅ Funções de mensagens tipadas | ⚠️ Apenas macros |
| Detecção de traduções ausentes | ✅ Erros de tipo e avisos de build | ⚠️ Fallback em runtime | ⚠️ Fallback para o idioma base | ⚠️ Fallback para texto de origem |
| Conteúdo rico (JSX, Markdown) | ✅ Suporte direto | ⚠️ Tags via t.rich | ⚠️ Strings | ✅ JSX dentro de <Trans> |
| Roteamento localizado | ✅ Integrado | ❌ Manual {-$locale} | ✅ urlPatterns + router rewrite | ❌ Manual {-$locale} |
| Troca de idioma sem recarregamento | ✅ Sim | ✅ Sim | ❌ Recarregamento completo | ✅ Sim |
| Pluralização | ✅ Baseada em enumeração | ✅ ICU | ✅ Variantes | ✅ ICU |
| ICU MessageFormat | ✅ Via format: "icu" | ✅ Nativo | ⚠️ Via plugin inlang | ✅ Nativo |
| Formatos de conteúdo | ✅ .ts, .json, .md, .yaml... | ⚠️ .json | ⚠️ JSON inlang | ✅ PO, JSON, CSV |
| Tradução com IA | ✅ Seu próprio provedor e chave | ❌ Não | ❌ Não | ❌ Não |
| Editor visual / CMS | ✅ Editor local + CMS opcional | ❌ Plataformas ext. | ⚠️ Apps do ecossistema inlang | ❌ Plataformas ext. |
| Ajudantes de SEO (hreflang, sitemap) | ✅ Integrados | ❌ Manual | ⚠️ URLs localizadas, resto manual | ❌ Manual |
| Tamanho do runtime (gzip, benchmark) | 4.5 KB | 75.9 KB | 1.8 KB | 56.7 KB |
| Vazamento, melhor config (idioma / pág) | 0% / 0% | 0% / 0% | 49.7% / 0% | 8.6% / 0% |
| Traduções ausentes no CI | ✅ npx intlayer test | ⚠️ Não integrado | ⚠️ Não integrado | ✅ lingui compile --strict |
Os números de tamanho de runtime e vazamento provêm do benchmark do TanStack Start. O vazamento é medido na melhor configuração de cada biblioteca.
Outros guias do TanStack Start: Lingui, use-intl e Intlayer.
Práticas que você deve seguir
- Defina
langedirna tag<html>a partir do idioma resolvido no servidor. - Mantenha uma URL por idioma com uma estratégia de prefixo (
/fr/about), para que cada versão de idioma seja indexável. - Coloque
urlem primeiro lugar na sua estratégia de idioma, para que a URL seja a fonte da verdade e os rastreadores recebam a página solicitada. - Use chaves de mensagem planas e descritivas (
about_title) que mapeiem de forma limpa para nomes de funções. - Faça o commit de
messages/*.json, não da pasta geradasrc/paraglide, para evitar conflitos de mesclagem em arquivos gerados. - Traduza seus metadados e declare
canonical,hreflangex-defaultem todas as páginas. - Gere um sitemap multilíngue e robots.txt, e faça a pré-renderização de todos os idiomas.
- Use links reais para o seletor de idiomas, para que os rastreadores descubram todas as línguas disponíveis.
Consulte nosso guia sobre internacionalização e SEO e o guia de hreflang.
Guia Passo a Passo para Configurar o Paraglide JS em uma Aplicação TanStack Start
Aqui está a estrutura de projeto que iremos criar:
Copiar o código para a área de transferência
Observe que não há pasta $locale: a reescrita do roteador remove o prefixo antes da correspondência da rota.
Instalar Dependências
Comece a partir de um projeto TanStack Start e, em seguida, inicialize o Paraglide. O comando init cria
project.inlang/settings.json, um primeiro arquivomessages/en.jsone instala o pacote.bashCopiar códigoCopiar o código para a área de transferência
- @inlang/paraglide-js: o compilador e seu plugin Vite. Não há pacote de runtime para instalar: o runtime é gerado dentro do seu próprio projeto.
Configurar Seus Idiomas
project.inlang/settings.jsoné a única fonte da verdade para os idiomas. O plugin de formato de mensagem lê um arquivo JSON por idioma.project.inlang/settings.jsonCopiar códigoCopiar o código para a área de transferência
Configurar o Plugin Vite e a Estratégia de URL
O plugin compila mensagens a cada alteração. Três opções são importantes para o TanStack Start:
strategy: a lista ordenada de locais de onde obter o idioma. Colocarurlem primeiro lugar torna a URL a fonte da verdade.cookieepreferredLanguagesão utilizados pelo middleware quando a URL não decide.urlPatterns: como um idioma é mapeado para uma URL. Os idiomas que não são o padrão são listados primeiro, pois o primeiro padrão correspondente vence. Aqui, o idioma padrão permanece sem prefixo (/about), e os outros idiomas recebem prefixo (/fr/about).outputStructure: "message-modules": um módulo por mensagem, o que permite que o empacotador descarte mensagens que uma página não importa.
vite.config.tsCopiar códigoCopiar o código para a área de transferência
Adicione a pasta gerada ao
.gitignore. Ela é reconstruída durantedevebuild:.gitignoreCopiar códigoCopiar o código para a área de transferência
Criar Seus Arquivos de Tradução
Cada chave se torna uma função exportada de
src/paraglide/messages. Chaves planas em snake_case produzem os nomes de função mais limpos. Variáveis usam marcadores{name}.messages/en.jsonCopiar códigoCopiar o código para a área de transferência
messages/fr.jsonCopiar códigoCopiar o código para a área de transferência
Plurais usam a sintaxe de variantes do formato de mensagens inlang:
messages/en.jsonCopiar códigoCopiar o código para a área de transferência
Adicionar o Middleware de Servidor
O middleware resolve o idioma de cada requisição com sua estratégia e o disponibiliza para
getLocale()durante toda a renderização no servidor, por meio de um escopoAsyncLocalStorage. É isso que torna seguras as requisições concorrentes em idiomas diferentes.No TanStack Start, envolva a entrada de servidor padrão:
src/server.tsCopiar códigoCopiar o código para a área de transferência
Reescrever URLs Localizadas no Roteador
A opção
rewritedo TanStack Router traduz URLs nas fronteiras do roteador:- entrada (input):
/fr/abouté deslocalizado para/aboutantes da correspondência, de modo que uma única rotaabout.tsxatenda a todos os idiomas; - saída (output): cada
hrefgerado (links, redirecionamentos, navegação) é localizado para o idioma ativo, de forma que<Link to="/about">renderize/fr/aboutem uma página em francês.
src/router.tsxCopiar códigoCopiar o código para a área de transferência
Como os links são localizados pela reescrita, você não precisa de um componente personalizado
LocalizedLink: utilize oLinknormal do TanStack Router.- entrada (input):
Criar o Documento Raiz
getLocale()retorna o idioma resolvido pelo middleware no servidor e o idioma da URL no navegador, garantindo quelangedirsejam idênticos no HTML do servidor e após a hidratação.src/i18n/config.tsCopiar códigoCopiar o código para a área de transferência
src/routes/__root.tsxCopiar códigoCopiar o código para a área de transferência
Utilizar Traduções nas Suas Páginas
Mensagens são funções simples: importe
m, chame a função e passe as variáveis como um objeto. Tudo é tipado, incluindo as variáveis.src/routes/index.tsxCopiar códigoCopiar o código para a área de transferência
src/routes/about.tsxCopiar códigoCopiar o código para a área de transferência
Uma função de mensagem também aceita um idioma explícito:
m.about_title({}, { locale: "fr" }). Isso é útil em código no servidor que renderiza um idioma diferente daquele da requisição, como em e-mails.Alterar o Idioma do Seu Conteúdo
OpcionalRenderize o seletor como links com
localizeHref, para que os rastreadores descubram todos os idiomas.setLocalearmazena a escolha no cookie e recarrega a página no novo idioma: o recarregamento completo é o comportamento esperado do Paraglide, pois as funções de mensagens leem o idioma a cada chamada em vez de se inscreverem em um estado do React.src/components/LocaleSwitcher.tsxCopiar códigoCopiar o código para a área de transferência
Internacionalizar Seus Metadados
OpcionalCada versão de idioma pode ranquear por conta própria, desde que cada página exponha:
- um
<title>edescriptiontraduzidos; - uma URL canônica (canonical) apontando para si mesma;
- uma tag alternate
hreflangpor idioma, além dox-default; - tags Open Graph
og:locale,og:locale:alternateeog:url; - JSON-LD com
inLanguage.
A função
localizeUrldo Paraglide constrói as URLs alternativas a partir de seusurlPatterns, para que nunca fiquem desalinhadas com o roteamento real:src/i18n/seo.tsCopiar códigoCopiar o código para a área de transferência
- um
Internacionalizar Seu Sitemap
OpcionalUm sitemap multilíngue lista cada URL de cada idioma, e cada entrada declara todas as suas alternativas com
xhtml:link:src/routes/sitemap[.]xml.tsCopiar códigoCopiar o código para a área de transferência
Internacionalizar Seu robots.txt
OpcionalRotas privadas existem em todos os idiomas, portanto as regras de
Disallowdevem cobrir cada caminho localizado. Removapublic/robots.txtse o template inicial tiver criado um, e sirva-o a partir de uma rota:src/routes/robots[.]txt.tsCopiar códigoCopiar o código para a área de transferência
Pré-renderizar Cada Idioma
OpcionalListe o caminho localizado de cada página para que o TanStack Start faça a pré-renderização de todas as versões de idioma.
localizeHrefé código gerado sem dependência de navegador, portanto pode ser executado emvite.config.ts, mas o arquivo só existe após a primeira compilação. Listar os caminhos manualmente, como abaixo, evita esse problema de ordem de execução:vite.config.tsCopiar códigoCopiar o código para a área de transferência
Como o seletor renderiza links reais,
crawlLinks: truetambém descobre páginas que você possa ter esquecido de listar.Gerenciar Páginas 404 Localizadas
OpcionalCom a reescrita,
/fr/does-not-existcorresponde a/does-not-exist, egetLocale()ainda retornafr, de modo que onotFoundComponentraiz da etapa 7 seja renderizado em francês. Uma rota catch-all garante que caminhos mais profundos também cheguem até ele. Marque a página comonoindex: o React 19 eleva o<meta>para o<head>.src/components/NotFound.tsxCopiar códigoCopiar o código para a área de transferência
src/routes/$.tsxCopiar códigoCopiar o código para a área de transferência
Acessar o Idioma em Funções de Servidor (Server Functions)
OpcionalFunções de servidor são executadas dentro do escopo do middleware do Paraglide, portanto
getLocale()funciona lá também:src/server/sendWelcomeEmail.tsCopiar códigoCopiar o código para a área de transferência
Comparar com o Intlayer
OpcionalNão existe um adaptador pronto do Paraglide para o Intlayer, porque ambos seguem a mesma ideia: compilar conteúdo no momento do build e enviar o mínimo possível de runtime. As diferenças residem no que chega ao navegador e em como o conteúdo é organizado:
- Idiomas: o Intlayer carrega dicionários dinâmicos por idioma (0% de vazamento de idioma no benchmark), enquanto cada função de mensagem do Paraglide carrega todos os idiomas (49.7%).
- Organização do conteúdo: o conteúdo pode ficar em arquivos
.content.tspróximos a cada componente ou em arquivos centralizados. Veja i18n por componente vs centralizado. - Troca de idioma: o conteúdo é lido de um contexto React, permitindo que a troca de idioma ocorra com re-renderização sem recarregar a página.
- Código gerado: nada é gerado dentro de
src, portanto não há nada para regenerar antes de um commit.
Se você estiver migrando de outra biblioteca em vez do Paraglide, os adaptadores de compatibilidade mantêm a API do
use-intl,next-intl,react-i18next,react-intlou Lingui e apenas trocam o runtime.Veja o Intlayer é mais leve que o Paraglide? e o guia TanStack Start com Intlayer.
Automatizar Suas Traduções Usando o Intlayer
OpcionalO Paraglide renderiza traduções, mas não ajuda você a produzi-las. O Intlayer é gratuito e código aberto, e seu conjunto de ferramentas ajuda mesmo em um projeto com Paraglide:
- Traduza com IA usando sua própria chave e provedor de API. Veja preenchimento automático (auto fill) e a CLI.
- Mantenha seus arquivos JSON como fonte da verdade com o plugin de sincronização JSON.
- Teste traduções ausentes no CI. Veja testando suas traduções.
- Analise seu site publicado em busca de tags
hreflangausentes, canônicos incorretos e vazamentos de idioma com o comando scan.
Perguntas Frequentes
É uma opção sólida: é utilizado nos exemplos oficiais do TanStack Router, possui o menor runtime do benchmark (~1.8 KB gzip) e as mensagens são totalmente tipadas. As desvantagens são que cada função de mensagem contém todos os idiomas, o que vaza cerca de metade das strings traduzidas para visitantes de outras línguas, e que trocar de idioma recarrega a página.
Não. O recurso rewrite do roteador remove o prefixo do idioma antes da correspondência da rota e o adiciona novamente aos links gerados, permitindo que um único about.tsx atenda a /about, /fr/about e /es/about.
As funções de mensagens leem o idioma no momento em que são chamadas e não estão inscritas em um estado do React. Portanto, setLocale recarrega a página por padrão para que todas as mensagens sejam re-renderizadas no novo idioma. Você pode passar { reload: false }, mas nesse caso precisará re-renderizar a árvore de componentes manualmente.
É preferível não versionar. A pasta é regenerada a cada execução de dev e build, e versioná-la causa conflitos de mesclagem em arquivos gerados. Em vez disso, faça commit de messages/*.json e project.inlang/settings.json.
Use localizeUrl para construir uma URL absoluta por idioma no método head() da rota e adicione uma tag x-default apontando para o idioma base. A etapa 10 fornece um utilitário reutilizável e a etapa 11 adiciona as mesmas alternativas ao sitemap.
Mensagens não utilizadas são descartadas quando você usa outputStructure: "message-modules", de modo que o conteúdo de outras páginas não vaze. Idiomas não utilizados não são descartados: cada função de mensagem contém todas as traduções, razão pela qual o benchmark registra um vazamento de idioma de 49.7%.
Comentários
Ainda sem comentários. Seja o primeiro a compartilhar seus pensamentos.
