Files
SnapOtter/apps/docs/pt-BR/guide/translations.md
T
SnapOtterandGitHub 4963ab3bbd feat(docs-i18n): translate all documentation into 20 languages
All 181 docs markdown files translated into 20 languages (apps/docs/<locale>/**). Companion to the i18n code PR; admin-merged because the file count exceeds GitHub's per-PR CI trigger limit. Validated by pnpm i18n:check (all surfaces, 0 stale/missing) and a clean all-locale docs build.
2026-07-11 13:52:47 +08:00

10 KiB

description, i18n_source_hash, i18n_provenance, i18n_output_hash
description i18n_source_hash i18n_provenance i18n_output_hash
21 idiomas suportados e como criar ou aprimorar traduções para o SnapOtter usando o sistema de i18n reforçado por TypeScript. 55837d9fdaef human 06674d601ead

Guia de tradução

O SnapOtter já vem com 21 idiomas prontos para uso. O sistema de i18n usa um runtime próprio e leve, com completude de locale garantida pelo TypeScript e code-splitting dinâmico.

Idiomas suportados

Code Language Native Name Direction
en Inglês English LTR
zh-CN Chinês (Simplificado) 简体中文 LTR
zh-TW Chinês (Tradicional) 繁體中文 LTR
ja Japonês 日本語 LTR
ko Coreano 한국어 LTR
es Espanhol Español LTR
fr Francês Français LTR
it Italiano Italiano LTR
pt-BR Português (Brasil) Português (Brasil) LTR
de Alemão Deutsch LTR
nl Holandês Nederlands LTR
sv Sueco Svenska LTR
ru Russo Русский LTR
pl Polonês Polski LTR
uk Ucraniano Українська LTR
ar Árabe العربية RTL
tr Turco Türkçe LTR
hi Híndi हिन्दी LTR
vi Vietnamita Tiếng Việt LTR
id Indonésio Bahasa Indonesia LTR
th Tailandês ไทย LTR

Como funciona a detecção de idioma

O SnapOtter usa uma ordem de resolução em três camadas:

  1. Preferência do usuário - armazenada em localStorage("snapotter-locale") e sincronizada com as configurações do usuário quando autenticado
  2. Detecção automática do navegador - percorre o array navigator.languages com correspondência de prefixo BCP 47
  3. Padrão da instância - a variável de ambiente DEFAULT_LOCALE do administrador (obtida de GET /api/v1/config/locale)
  4. Fallback para inglês - sempre disponível

Os usuários podem alterar o idioma a partir de:

  • O seletor Globo no rodapé (desktop, sempre visível)
  • O seletor de idioma da página de login (pré-autenticação)
  • A seção Configurações > Geral (preferência por usuário)
  • O menu suspenso de idioma da barra lateral móvel
  • A seção Configurações > Sistema define o padrão para toda a instância (somente administrador)

Como funcionam as traduções

Todas as strings da interface ficam em packages/shared/src/i18n/. O arquivo de referência é en.ts, que exporta um objeto tipado com todas as strings que o app usa (~1500 chaves). Os demais idiomas são arquivos separados (por exemplo, de.ts, fr.ts) que exportam a mesma estrutura.

O tipo TranslationKeys usa DeepStringRecord para aceitar qualquer valor de string enquanto impõe a estrutura das chaves. O TypeScript detecta chaves faltantes em qualquer arquivo de tradução em tempo de compilação.

Apenas o locale ativo é carregado em runtime via import() dinâmico, mantendo o bundle principal pequeno.

Usando traduções em componentes

import { useTranslation } from "@/contexts/i18n-context";
import { format, plural } from "@/lib/format";

function MyComponent() {
  const { t, locale, setLocale } = useTranslation();
  
  return (
    <div>
      <h1>{t.common.settings}</h1>
      <p>{format(t.settings.people.deleteConfirm, { username: "admin" })}</p>
      <p>{plural(count, t.automate.fileCount, t.automate.fileCountPlural)}</p>
    </div>
  );
}

Contribuindo com uma tradução

Aceitamos PRs de tradução diretamente. Você pode aprimorar um locale existente ou adicionar um novo.

Para relatar uma tradução incorreta sem enviar código, abra uma GitHub Issue com o idioma, a string incorreta e a correção sugerida.

::: tip PRs de tradução não exigem aprovação prévia. Faça um fork do repositório, faça suas alterações e abra um PR. Consulte o Guia de Contribuição para o processo completo de PR e o requisito de CLA. :::

Como criar ou atualizar uma tradução

1. Faça o fork e clone

git clone https://github.com/<your-username>/snapotter.git
cd snapotter
pnpm install

2. Copie o arquivo de referência (apenas novo idioma)

Pule esta etapa se você estiver aprimorando uma tradução existente.

cp packages/shared/src/i18n/en.ts packages/shared/src/i18n/XX.ts

3. Traduza as strings

Abra seu novo arquivo e traduza cada valor de string. Mantenha a estrutura do objeto e as chaves exatamente iguais.

import type { TranslationKeys } from "./en.js";

export const xx: TranslationKeys = {
  common: {
    upload: "Your translation here",
    // ... translate all entries
  },
  // ... translate all sections
} as const;

Regras:

  • Não traduza as chaves do objeto, apenas os valores de string
  • Mantenha as const no final
  • Importe TranslationKeys de ./en.js e tipe sua exportação
  • Mantenha os placeholders {variable} exatamente como estão
  • Os arrays (rotatingPhrases, progressMessages) devem ter o mesmo número de entradas
  • Não traduza: SnapOtter, JPEG, PNG, WebP, EXIF, API e outros termos técnicos

4. Registre o locale (apenas novo idioma)

Adicione seu locale a SUPPORTED_LOCALES em packages/shared/src/i18n/index.ts:

{ code: "xx", name: "Language Name", nativeName: "Native Name", dir: "ltr" },

5. Verifique

pnpm typecheck    # catches missing or mistyped keys
pnpm lint         # formatting check
pnpm dev          # manually verify strings appear correctly

6. Envie

Abra um PR contra main com um título como feat(i18n): add Swedish translation ou fix(i18n): correct German typos. O bot do CLA pedirá que você assine na sua primeira contribuição.

Adicionando novas chaves de tradução

Ao adicionar um novo recurso que precise de novas strings de interface:

  1. Adicione as novas chaves a en.ts primeiro (o arquivo de referência)
  2. Execute pnpm typecheck - cada arquivo de locale falhará se estiver sem a nova chave
  3. Adicione a nova chave a todos os arquivos de locale (use o inglês como fallback temporário)

Configuração

Defina o idioma padrão da instância por meio de variável de ambiente:

DEFAULT_LOCALE: "de"  # German as the default for all new users

Referência de arquivos

File Purpose
packages/shared/src/i18n/en.ts Strings em inglês (locale de referência, ~1500 chaves)
packages/shared/src/i18n/index.ts SUPPORTED_LOCALES, loadTranslations(), exportações de tipos
packages/shared/src/i18n/<locale>.ts Arquivos de tradução por idioma
apps/web/src/contexts/i18n-context.tsx I18nProvider, hook useTranslation()
apps/web/src/lib/format.ts Helpers format(), plural(), formatFileSize()
apps/api/src/routes/config.ts Endpoint público GET /api/v1/config/locale

Traduzindo o site, a documentação e a referência da API

O suporte a 21 idiomas descrito acima cobre o app. O site público (snapotter.com), este site de documentação e a referência da API REST também são traduzidos para todos os 21 idiomas, por um pipeline separado protegido por hash que reutiliza os mesmos nomes e descrições de ferramentas de packages/shared/src/i18n, de modo que a terminologia permaneça consistente em toda parte.

Traduzido por máquina por padrão

Toda página que não seja em inglês no site e na documentação é traduzida por máquina na primeira passagem (por uma sessão do Claude Code, não por um serviço de terceiros) e traz um pequeno banner dispensável dizendo isso, com um link de volta para cá. Isso é deliberado: entrega todos os 21 idiomas com rapidez e honestidade e, então, convida a comunidade a refinar as páginas que mais importam. A tradução por máquina transmite o significado; a revisão humana faz o texto soar natural.

Como o pipeline decide o que traduzir

Cada unidade traduzível do texto-fonte em inglês é submetida a hash, e o hash é armazenado ao lado de sua tradução. A cada execução, o pipeline:

  • traduz qualquer unidade que ainda não tenha tradução,
  • pula qualquer unidade cujo hash armazenado ainda corresponda ao texto-fonte em inglês,
  • retraduz uma unidade de máquina quando seu texto-fonte em inglês muda,
  • e sinaliza uma unidade refinada por humano como stale (precisa de revisão) quando seu texto-fonte em inglês muda, em vez de sobrescrever seu trabalho.

Refinando uma tradução da web por PR

Você aprimora uma tradução do site, da documentação ou da referência da API da mesma forma que aprimora um locale do app: editando o arquivo gerado e abrindo um PR.

  1. Encontre a tradução gerada para o seu idioma:
    • strings de interface do site: apps/landing/src/i18n/<locale>.json
    • uma página da documentação: apps/docs/<locale>/**.md
    • a referência da API: apps/api/src/openapi.<locale>.yaml
  2. Edite o texto. Mantenha código, links, {placeholders} e quaisquer marcadores ⸤I18N…⸥ exatamente como estão; o validador do pipeline rejeita uma tradução que remova ou reordene esses elementos.
  3. Abra um PR. Editar uma unidade muda sua proveniência de machine para human, de modo que o pipeline nunca a sobrescreverá em uma execução posterior. Se o texto-fonte em inglês mudar depois, sua unidade é sinalizada como stale para revisão, em vez de ser substituída silenciosamente.

Para relatar uma tradução incorreta sem enviar código, abra uma GitHub Issue com a URL da página, o idioma, o texto incorreto e sua correção sugerida.

::: tip Os mantenedores executam o pipeline de tradução; você não precisa de uma chave de API para contribuir. Basta editar o arquivo gerado e abrir um PR. Consulte scripts/i18n/README.md para saber como o pipeline funciona. :::