Skip to content

Rótulos multilíngues

O GCM vem com inglês, espanhol, francês, e português como idiomas de UI suportados. As strings de UI (rótulos de botões, itens de menu, mensagens de erro) vêm dos arquivos de tradução i18n/locales/<lang>.json mantidos pela plataforma. Mas os dados — seus tipos de membros, seus nomes de reuniões, seus países, seus estados civis — vivem no banco de dados. Para fazer esses rótulos seguirem o idioma escolhido pelo usuário, cada tabela de referência tem uma coluna translations JSONB.

Esse artigo cobre o que tem nessa coluna, quando você deve preencher, e como a renderização volta quando uma tradução está faltando.

Diálogo de entrada de traduções

A forma das traduções

Cada linha de tabela de referência tem uma coluna JSONB chamada translations com essa forma:

jsonc
{
  "en": { "name": "Visitor" },
  "es": { "name": "Visitante" },
  "fr": { "name": "Visiteur" },
  "pt": { "name": "Visitante" }
}

As chaves de nível superior são códigos de locale (en, es, fr, pt). O valor de cada uma é um objeto de nome do campo → string traduzida. A maioria das linhas de referência só tem um campo name hoje, mas a mesma coluna estende de forma limpa para outros campos localizáveis (descrição, forma plural) sem uma migração.

Códigos de locale batem com a constante SUPPORTED_LOCALES em src/shared/lib/i18n-localize.ts:

CódigoIdioma
enEnglish
esEspañol
frFrançais
ptPortuguês

Como a resolução funciona

Quando a UI precisa renderizar o nome de uma linha, ela chama o helper localize() com as traduções da linha, a coluna name legada como fallback, e o locale ativo do usuário:

ts
localize(row.translations, row.name, language, "name")

O helper anda quatro passos de resolução em ordem:

  1. translations[locale][field] — acerto exato no locale solicitado.
  2. translations.en[field] — fallback para inglês.
  3. row[field] — a coluna canônica legada. (Para tipos de membros, isso é member_types.name.)
  4. String vazia — chamador pode renderizar um placeholder.

Então um usuário em espanhol vendo um tipo de membro sem tradução em espanhol vê o rótulo em inglês em vez de uma célula em branco. Um usuário vendo uma reunião em português — um locale menos traduzido — vê português se disponível, depois inglês, depois a coluna name bruta. Nenhum locale silenciosamente mostra uma célula vazia.

Quando você deve preencher traduções

O custo de UX de deixar traduções em branco é pequeno (fallback para inglês) mas visível para seus congregantes bilíngues. Três regras gerais:

Sempre traduza se sua congregação é bilíngue

Se você prega regularmente em dois idiomas ou tem membros que só leem um, preencha ambos os rótulos toda vez que adiciona uma linha de referência. Os 20 segundos que leva quando você adiciona um tipo de membro economiza um rótulo só-inglês constrangedor no perfil de um membro em espanhol.

Traduza as listas gerenciadas pela plataforma também

Países, estados, cidades, gêneros, estados civis — esses vêm pré-traduzidos pela plataforma mas a cobertura não é 100%. Se você notar que um país ou estado mostra inglês na sua UI em espanhol, você pode sinalizar via suporte e o admin de plataforma vai preencher o locale faltando.

Pule traduções se você é monolíngue

Se toda sua congregação fala um idioma e você não tem planos de adicionar outro, pule a entrada de traduções. A cadeia de fallback garante que o nome canônico renderiza corretamente. Você sempre pode voltar e preencher depois — adicionar uma tradução nunca move a linha, só adiciona ao JSONB.

A UI de entrada de traduções

Quando você adiciona ou edita uma linha de referência, o diálogo mostra uma entrada Traduções.

Parece uma entrada de texto com abas — uma aba por locale suportado, com padrão para inglês. Digite o rótulo em inglês primeiro (que espelha na coluna canônica name), depois alterne para as abas em espanhol / francês / português para preencher o resto.

As abas que você vê dependem de SUPPORTED_LOCALES. Adicionar um novo idioma de plataforma é uma mudança de uma linha em i18n-localize.ts mais distribuir o arquivo de traduções de UI correspondente — sem migração de banco. Linhas existentes só têm entradas vazias para o novo locale até você preencher.

Tradução em massa

Para admins de org configurando um tenant em espanhol novo em folha, o caminho mais rápido é:

  1. Adicione cada tipo de membro em inglês primeiro.
  2. Abra o banco pelo módulo Registros de Dados ou seu projeto Supabase.
  3. Use um único UPDATE: UPDATE member_types SET translations = jsonb_set(translations, '{es,name}', '"<spanish name>"') WHERE name = '<english name>'.
  4. Atualize a UI — cada membro já atribuído a esse tipo agora mostra o rótulo em espanhol.

Admins de plataforma podem fazer isso para as tabelas de referência globais (gêneros, estados, geografia) sob demanda.

O que é traduzido onde

TabelaCampoQuem preenche
member_typesnameAdmin org
meetingsnameAdmin org
gendersnameAdmin de plataforma
relationship_statusesnameAdmin de plataforma
countriesnameAdmin de plataforma
statesnameAdmin de plataforma
citiesnameAdmin de plataforma
pages (construtor de site)title, bodyAdmin org (UI separada)
notificationssubject, bodyAdmin org (UI separada)
eventstitle, descriptionAdmin org (editor de eventos)

O padrão é consistente pela plataforma: onde quer que dados inseridos pelo usuário precisem seguir o idioma do visualizador, a linha recebe uma coluna translations JSONB e a UI a lê pelo mesmo helper localize().

Histórico de migração

A coluna translations foi adicionada em toda a plataforma na migração 20260518020000_translations_jsonb_system junto com o helper localize(). Antes disso, tabelas individuais tinham colunas _es (ex. meetings.name_es) que eram inconsistentes e não estendiam para novos idiomas. Essas colunas _es foram migradas para fora de reuniões, meses, eventos, páginas, e notificações — veja os docs de codebase para a referência canônica.

Se você encontrar uma coluna _es antiga em src/integrations/supabase/types.ts, é uma sobra no arquivo de tipos auto-gerado em vez de algo em que você deveria escrever. Sempre escreva pela coluna translations JSONB.

E se eu precisar de um quinto idioma?

Adicione o código de locale a SUPPORTED_LOCALES em src/shared/lib/i18n-localize.ts, distribua um arquivo src/i18n/locales/<code>.json correspondente com as strings de UI, e o banco está pronto sem uma migração. Linhas existentes ganham uma entrada vazia para o novo locale; admins preenchem ao longo do tempo. Envie e-mail à equipe de engenharia se seu tenant precisa de um idioma que não está na lista suportada.

Próximo