Dicionários e Providers i18n do Next.js (nextjs-i18n-usage)
Padrões de engenharia, hooks e patterns de provider para consumir traduções next-intl em Componentes React Server, Componentes Cliente, histórias Storybook e harnesses de teste.
[!TIP] Padrões de Implementação: Consulte
references/examples.mdpara exemplos completos de código (RSC, formulários Cliente, trocadores de idioma, decoradores Storybook e wrappers de teste). Execução Rápida: Delegue validação de dicionário ou sincronização de chaves a um subagente leve (Model: 'flash').
1. Contrato de Zero-Hardcoding
- Zero Texto Hardcoded: Nunca escreva labels voltadas ao usuário, placeholders ou strings de fallback em JSX.
- Sem Objetos Mock: Dicionários mock inline (ex.:
const DEFAULT_CONTENT = {...}) são PROIBIDOS. - Sincronização Síncrona: Ao adicionar/atualizar cópia de UI, insira traduções autênticas em TODOS os arquivos de locale em
messages/[locale].json(ex.:messages/en.jsonemessages/fa.json) antes de escrever JSX.
2. Referência Rápida de API & Hooks
| Ambiente / Alvo | Hook / API | Exemplo de Sintaxe |
|---|---|---|
| Componente Server (RSC) | getTranslations | const t = await getTranslations('namespace'); |
| Formatador Server | getFormatter | const format = await getFormatter(); format.dateTime(...) |
| Metadados Dinâmicos | getTranslations | export async function generateMetadata({ params }) { ... } |
| Componente Cliente | useTranslations | const t = useTranslations('namespace'); |
| Formatador Cliente | useFormatter | const format = useFormatter(); format.number(...) |
| Texto Rico (Cliente) | t.rich | t.rich('terms', { link: (c) => <Link href="/t">{c}</Link> }) |
| Navegação | @/i18n/navigation | import { Link, useRouter, usePathname } from '@/i18n/navigation'; |
| Preview Storybook | NextIntlClientProvider | Envolva o decorator preview com <NextIntlClientProvider locale="en" messages={enMessages}> |
| Testes Unitários (Jest) | renderWithIntl | Envolva o render com <NextIntlClientProvider locale="en" messages={messages}> |
3. BiDi (LTR / RTL) & Padrões de Estilização
- Apenas Propriedades Lógicas Tailwind:
- Proibido:
ml-*,mr-*,pl-*,pr-*,left-*,right-*,text-left,text-right - Obrigatório:
ms-*,me-*,ps-*,pe-*,start-*,end-*,text-start,text-end
- Proibido:
- Direção Dinâmica:
<html dir="rtl">dinâmico parafa/aredir="ltr"paraen.
4. Anti-Padrões & Armadilhas
| Erro | Causa Raiz | Solução |
|---|---|---|
useTranslations em RSC | Hooks não podem rodar em Server Components assíncronos | Use await getTranslations('ns') |
getTranslations em Cliente | Função assíncrona exclusiva do server | Use useTranslations('ns') com "use client" |
| "Nenhum contexto intl encontrado" | Provider faltando no Storybook/teste | Envolva história/teste em <NextIntlClientProvider> |
| Fallbacks Hardcoded | Ex.: `t('btn') | |
next/link cru | Remove prefixo de locale na mudança de rota | Use Link de @/i18n/navigation |
5. Verificação de Paridade
Execute a verificação de paridade de dicionário:
pwsh .agents/skills/nextjs-i18n-usage/scripts/verify-dictionaries.ps1