A interface de administração do EmDash é traduzível usando o Lingui para extração de mensagens e o Lunaria para acompanhamento do progresso das traduções. Todas as traduções ficam em arquivos PO (gettext) — um por locale.
Estado das traduções
Consulte o painel de traduções para ver o progresso atual de todos os locales.
Quem pode traduzir
As traduções devem vir de falantes nativos ou fluentes. Não aceitamos traduções geradas por máquina. Se você usar ferramentas de IA para auxiliar, deve revisar cada string manualmente e testar o resultado em contexto (veja Testando suas traduções abaixo).
Preferimos que uma string fique sem tradução do que com uma tradução ruim. Uma tradução errada é pior do que exibir o texto em inglês como fallback — ela induz os usuários ao erro ativamente.
Estrutura de arquivos
Os catálogos de tradução ficam em packages/admin/src/locales/:
packages/admin/src/locales/
├── en/
│ └── messages.po # English (source)
├── de/
│ └── messages.po # German
└── ...
Cada arquivo .po contém pares msgid/msgstr. O msgid é o texto fonte em inglês; o msgstr é a sua tradução. Um msgstr vazio significa “ainda não traduzido” — o Lingui usará o inglês como fallback em tempo de execução.
Traduzindo strings
-
Consulte o painel de traduções para ver o que precisa de trabalho. Verifique PRs abertos para evitar duplicação de esforço.
-
Faça fork do repositório e crie uma branch:
git checkout -b i18n/de -
Abra o arquivo PO do seu locale (ex.:
packages/admin/src/locales/de/messages.po). -
Preencha as traduções. Cada entrada tem esta aparência:
#: packages/admin/src/components/LoginPage.tsx:304 msgid "Sign in with Passkey" msgstr ""Preencha o
msgstr:#: packages/admin/src/components/LoginPage.tsx:304 msgid "Sign in with Passkey" msgstr "Mit Passkey anmelden" -
Teste suas traduções (veja abaixo).
-
Abra um PR direcionado a
main. Formato do título:i18n(de): add/update German translations.
O que traduzir
- O valor
msgstrde cada entrada.
O que NÃO traduzir
- Valores
msgid— são chaves de busca. - Marcadores de interpolação como
{error},{email},{label}— mantenha-os exatamente como estão. - Tags estilo XML como
<0>,</0>— envolvem elementos interativos (links, botões). Mantenha as tags e traduza o texto entre elas. - Comentários que começam com
#:— são referências ao código fonte adicionadas pelo Lingui.
Interpolação e tags
Algumas strings contêm marcadores e tags:
msgid "Authentication error: {error}"
msgstr "Authentifizierungsfehler: {error}"
msgid "Don't have an account? <0>Sign up</0>"
msgstr "Noch kein Konto? <0>Registrieren</0>"
msgid "If an account exists for <0>{email}</0>, we've sent a sign-in link."
msgstr "Falls ein Konto für <0>{email}</0> existiert, haben wir einen Anmeldelink gesendet."
Marcadores ({error}, {email}) são substituídos por valores dinâmicos em tempo de execução. Tags (<0>...</0>) envolvem componentes React. Ambos devem aparecer na sua tradução exatamente como no texto fonte — mesmos nomes, mesma aninhamento.
Testando suas traduções
-
Compile e execute a demo:
pnpm run locale:compile pnpm build pnpm --filter emdash-demo dev -
Mude o locale na página de Configurações da administração e verifique se suas traduções estão corretas em contexto.
Locale pseudo
O EmDash inclui um locale pseudo que transforma todas as strings envolvidas em caracteres acentuados semelhantes — "Dashboard" se torna "Ðàšĥƀöàřð", e assim por diante. Qualquer string que apareça em inglês normal enquanto o locale pseudo está ativo está sem o wrapper t..“ ou vem de fora do catálogo.
Para ativá-lo, adicione o seguinte ao seu arquivo .env no diretório da demo:
EMDASH_PSEUDO_LOCALE=1
Em seguida, reinicie o servidor de desenvolvimento. O locale pseudo aparece como Pseudo no seletor de idioma na página de login e nas Configurações. Mude para ele para identificar strings não envolvidas rapidamente.
Adicionando um novo idioma
Se o seu idioma ainda não tem um arquivo PO:
-
Adicione o locale a
packages/admin/src/locales/locales.ts:export const LOCALES: LocaleDefinition[] = [ { code: "en", label: "English", enabled: true }, { code: "de", label: "Deutsch", enabled: true }, // ... { code: "ja", label: "日本語", enabled: false }, // add yours ];Esta é a única fonte de verdade —
lingui.config.ts,lunaria.config.tse o runtime da administração derivam suas listas de locales deste arquivo. Definaenabled: falsea menos que suas traduções tenham cobertura de 100% — habilitaremos quando a tradução atingir cobertura suficiente. -
Execute a extração para gerar o arquivo PO vazio:
pnpm run locale:extractIsso cria
packages/admin/src/locales/{your-locale}/messages.pocom todas as strings prontas para traduzir. -
Traduza e teste seguindo os passos acima.
Padrões de tradução
Precisão
As traduções devem refletir fielmente o texto fonte em inglês no nível de um falante nativo. Não adicione, remova ou reinterprete significados. Se uma string fonte for ambígua, verifique o comentário #: para a localização do arquivo fonte — leia o código do componente para entender o contexto.
Consistência
Use terminologia consistente dentro do seu locale. Se você traduzir “collection” como “Sammlung” em um lugar, não mude para “Kollektion” em outro. Se o seu idioma já tem traduções, leia o arquivo PO existente antes de começar para se alinhar com a terminologia estabelecida.
Tom
A interface de administração usa um tom direto e profissional. Mantenha esse mesmo tom no seu idioma — evite formulações excessivamente formais ou excessivamente informais.
Traduções assistidas por IA
Você pode usar ferramentas de IA para rascunhar traduções, mas:
- Você deve revisar cada string pessoalmente. Ferramentas de IA cometem erros sutis que apenas um falante fluente perceberia — registro incorreto, fraseado não natural, termos técnicos errados.
- Você deve testar o resultado na interface de administração em execução. Ferramentas de IA não têm consciência das restrições de layout ou do contexto da interface.
- Declare o uso de IA na descrição do seu PR.
- PRs com traduções automáticas evidentemente não revisadas serão fechados.
Traduções parciais
Traduções parciais são bem-vindas. Você não precisa traduzir todas as strings em um único PR — qualquer progresso ajuda. Strings não traduzidas usarão o inglês como fallback em tempo de execução.