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
- "Histórico inicial"v9.3.112/08/2026
O conteúdo desta página foi traduzido com uma IA.
Veja a última versão do conteúdo original em inglêsIf you have an idea for improving this documentation, please feel free to contribute by submitting a pull request on GitHub.
GitHub link to the documentationCopy doc Markdown to clipboard
Plugin ESLint x OXLint
O eslint-plugin-intlayer detecta os tipos de erros de i18n que o TypeScript não consegue identificar:
- Texto codificado diretamente (hardcoded) que nunca chegou a um dicionário.
- Chamadas dinâmicas que passam na verificação de tipos e são executadas, mas que o compilador do Intlayer não consegue otimizar.
- Conteúdo morto — dicionários e campos que nada no projeto lê (ativação opcional).
Chaves de dicionário desconhecidas, caminhos de campos desconhecidos e idiomas ausentes já são erros de compilação, portanto o plugin não os repete.
Instalação
Copiar o código para a área de transferência
npm install --save-dev eslint-plugin-intlayerRequer o ESLint 9 ou superior (flat config). O ESLint 10 é compatível.
Utilização
O plugin funciona tanto no ESLint quanto no oxlint — com as mesmas regras e as mesmas opções.
Ou espalhe uma configuração e defina você mesmo as severidades:
Configurações
Abrir a tabela em um modal para ver todo o conteúdo claramente
| Configuração | no-raw-text | static-dictionary-key | no-dynamic-field-access | enforce-adapter-import | no-unused-content |
|---|---|---|---|---|---|
recommended | warn | error | error | off | off |
strict | error (+ literais fora de JSX) | error | error | error | off |
contract-only | off | error | error | off | off |
A configuração recommended mantém deliberadamente no-raw-text como warn: apontá-la para uma base de código existente traz à tona todas as strings não traduzidas de uma só vez, o que não deve quebrar a sua compilação logo no primeiro dia.
O enforce-adapter-import fica desativado por padrão — ative-o explicitamente se desejar.
O no-unused-content fica desativado em todas as configurações, inclusive na strict. É a única regra que lê sua configuração do Intlayer e percorre seus arquivos de código no disco; portanto, ativá-la deve ser uma escolha consciente e não algo imposto por uma predefinição.
Regras
no-raw-text
Reporta texto voltado ao usuário que não esteja declarado em um dicionário. Ele usa a mesma detecção do intlayer extract, portanto nomes de marcas, classes CSS e identificadores técnicos são ignorados.
Copiar o código para a área de transferência
// ✗ Reportado<h1>Welcome to our documentation</h1><input placeholder="Enter your email address" />// ✓ Corretoconst { title } = useIntlayer("home");<h1>{title}</h1>Arquivos de declaração de conteúdo (*.content.ts, …) são ignorados.
Para corrigir um arquivo inteiro de uma só vez, execute npx intlayer extract e deixe o compilador mover as strings para um dicionário para você.
Opções
static-dictionary-key
Exige que a chave do dicionário seja uma string literal.
O compilador só consegue pré-carregar um dicionário quando pode ler a chave diretamente no local da chamada. Com uma chave calculada, ele pula silenciosamente a otimização e inclui todos os dicionários no bundle.
Copiar o código para a área de transferência
// ✗ ReportadouseIntlayer(dictionaryKey);useIntlayer(`home-${suffix}`);getTranslations({ namespace: page });// ✗ Uma variável ainda não é um literalconst key = "home";useIntlayer(key);// ✓ CorretouseIntlayer("home");getTranslations({ namespace: "home" });Isso se aplica ao useIntlayer, getIntlayer e a todos os adaptadores de compatibilidade (useTranslation, useTranslations, formatMessage, <FormattedMessage id>, <Trans i18nKey>, …).
no-dynamic-field-access
Exige que o campo lido de um dicionário seja conhecido estaticamente.
O compilador remove campos que não são identificados como utilizados. Um acesso computado é invisível para ele, portanto a leitura pode retornar undefined em tempo de execução.
Copiar o código para a área de transferência
// ✗ Reportadoconst content = useIntlayer("home");content[fieldName];const t = useTranslations("home");t(messageKey);// ✓ Corretocontent.title;content["title"];content.items[0];t("hero.title");enforce-adapter-import
Prefere o adaptador de compatibilidade @intlayer/* ao pacote original. O original só é resolvido para o Intlayer quando o alias do empacotador está configurado; o adaptador sempre funciona. Corrigível automaticamente com --fix.
Copiar o código para a área de transferência
// ✗ Reportadoimport { useTranslation } from "react-i18next";import { getTranslations } from "next-intl/server";// ✓ Corretoimport { useTranslation } from "@intlayer/react-i18next";import { getTranslations } from "@intlayer/next-intl/server";no-unused-content
Desativada por padrão. Reporta conteúdo que nada em seu projeto lê, além de chaves de dicionário declaradas em mais de um local.
Copiar o código para a área de transferência
export default { key: "home", // ✗ Reportado se nenhum chamador no projeto solicitar "home" content: { title: t({ pt: "Título", en: "Title" }), // ✗ Reportado se nada ler `hero` hero: { subtitle: t({ pt: "Subtítulo", en: "Subtitle" }), }, },};Ao contrário das outras regras, esta não pode responder apenas com base no arquivo analisado — um campo só é considerado não utilizado em relação ao projeto inteiro. Na primeira declaração de conteúdo de uma execução do linter, ela carrega a sua configuração do Intlayer, busca os arquivos de código declarados por essa configuração (build.traversePattern, compiler.transformPattern) e executa o mesmo analisador de uso que alimenta o @intlayer/lsp e o tachado de "não utilizado" na extensão do VS Code. O resultado é armazenado em cache por cacheTtl milissegundos, para que a varredura ocorra uma vez por execução e não a cada arquivo.
Opções
Diminua cacheTtl ao executar o lint a partir de um servidor de editor de longa duração e quiser que as alterações apareçam mais rápido; defina baseDir quando uma única execução de lint cobrir vários projetos Intlayer em um monorepo.
Tende ao silêncio. Um falso positivo aqui apagaria uma tradução; portanto, nada é reportado quando o dicionário é consumido de uma forma que a análise não consiga rastrear: o objeto de conteúdo passado por completo, uma função de tradução vinculada a partir dele (const t = useTranslations("home")), uma declaração acessada por importação direta (useDictionary(myDictionary)), umnest()de outro dicionário ou uma lista de campos tornada não exaustiva por um spread. Componentes de arquivo único (.vue,.svelte,.astro) são considerados como usuários de todos os campos dos dicionários mencionados, pois seus blocos de script não são analisados aqui.
O reportDuplicateKeys lê os dicionários não mesclados que o build grava em .intlayer/, portanto permanece em silêncio até que o projeto tenha sido construído pelo menos uma vez. Duas declarações compartilhando uma chave são mescladas, o que é um padrão válido — o aviso existe porque um campo definido em ambos os lados mantém silenciosamente apenas um dos dois valores.
O analisador é carregado a partir do @intlayer/lsp, distribuído como ESM. A regra requer, portanto, uma versão do Node compatível com require() em módulos ES — Node 20.19+ ou 22.12+. Em versões anteriores, ela não reporta nada em vez de falhar a execução do lint.
Frameworks
Todas as regras funcionam em todas as integrações do Intlayer, inclusive dentro de templates Vue, Svelte e Angular. Você só precisa informar ao ESLint qual parser lê cada tipo de arquivo.
Abrir a tabela em um modal para ver todo o conteúdo claramente
| Framework | Arquivos | Parser |
|---|---|---|
| React, Preact, Solid, Lit | .jsx .tsx | typescript-eslint |
| Next.js | .jsx .tsx | typescript-eslint |
| Vue, Nuxt | .vue | vue-eslint-parser |
| Svelte, SvelteKit | .svelte | svelte-eslint-parser |
| Angular | .ts | typescript-eslint |
| Templates do Angular | .component.html | @angular-eslint/template-parser |
| Astro | .astro | astro-eslint-parser |
Instale apenas os parsers de que seu projeto precisa.
Limitação conhecida. Em templates do Vue e Angular, uma expressão como{{ content[key] }}não é verificada pelono-dynamic-field-access. Leituras dinâmicas escritas no bloco script são identificadas normalmente.