Pular para o conteúdo principal

Internacionalizacao (i18n)

O template usa @cactus-agents/i18n com selecao de idioma em build-time. Apenas um idioma entra no bundle do cliente — zero overhead de idiomas nao utilizados.

Como funciona

Build-time
|
v
Vite alias ~i18n → @cactus-agents/i18n/locales/{BRAND_LANGUAGE}
|
v
import common from "~i18n/common.json" (resolve para pt-br/common.json)
|
v
initI18n({ language, resources, overrides })
|
v
<TranslationProvider> (react-i18next I18nextProvider)
|
v
useTranslation("namespace") em qualquer componente

Configuracao

context/i18n.tsx

O TranslationProvider importa todos os 10 namespaces estaticamente e inicializa o i18next:

import common from "~i18n/common.json";
import auth from "~i18n/auth.json";
import countries from "~i18n/countries.json";
import payments from "~i18n/payments.json";
import casino from "~i18n/casino.json";
// ... (10 namespaces)

const resources = {
common,
auth,
countries,
payments,
casino,
user,
validation,
sports,
gamification,
layout,
};
const overrides = loadOverrides(); // import.meta.glob de app/locales/overrides/

initI18n({ language: __BRAND_LANGUAGE__, resources, overrides });

Variaveis de ambiente

VariavelContextoDescricao
BRAND_LANGUAGEBuild-time (Vite define)Idioma do build: pt-br, en, es, es-mx

O Vite injeta __BRAND_LANGUAGE__ como constante global.

Idiomas suportados

CodigoIdioma
pt-brPortugues (Brasil)
enIngles
esEspanhol
es-mxEspanhol (Mexico)

Nota: es-mx usa os locales es do SDK como base com overrides especificos do fork.

Namespaces

NamespaceDescricaoExemplos de chaves
commonUI genericabutton.save, status.active, error.network
authAutenticacaologin.email, register.password, forgot_password.title
countriesPaises/nacionalidadesnationalities.BRA, countryNames.MEX
paymentsPagamentosdeposit.amount, withdraw.confirm, pix.qr_code
casinoCassinocasino.popular, search.no_results, detail.rtp
userContaaccount.name, wallet.balance, protection.self_exclusion
validationValidacoessteps.email.title, blocker.message, kyc_reasons.password_change
sportsEsportestitle, live, my_bets
gamificationVIPmissions.daily, tournaments.prize_pool, store.redeem
layoutApp shellheader.deposit, sidebar.casino, footer.copyright

:::warning Renomeacao de namespace O namespace de cassino foi renomeado de games para casino. O arquivo de traducao correspondente e casino.json em cada locale. Uso: useTranslation("casino"). :::

Uso em componentes

import { useTranslation } from "react-i18next";

function DepositButton() {
const { t } = useTranslation("payments");
return <button>{t("deposit.submit")}</button>;
}

// Multiplos namespaces
function Header() {
const { t } = useTranslation(["layout", "common"]);
return <span>{t("layout:header.deposit")}</span>;
}

// Interpolacao
function Greeting({ name }: { name: string }) {
const { t } = useTranslation("common");
return <span>{t("greeting", { name })}</span>;
}

Overrides de fork

Forks podem sobrescrever chaves especificas sem duplicar o JSON inteiro:

Estrutura

app/locales/overrides/
├── common.json (opcional)
├── auth.json (opcional)
├── payments.json (opcional)
└── ...

Exemplo — override de common.json

{
"button": {
"save": "Gravar"
}
}

Apenas button.save e sobrescrito. Todas as outras chaves de common mantem os valores do SDK.

Como funciona

O loadOverrides() usa import.meta.glob("~/locales/overrides/*.json", { eager: true }) para descobrir os arquivos em build-time. O deepMerge do SDK faz o merge recursivo.

Adicionando um novo namespace

  1. Criar JSONs em @cactus-agents/i18n/locales/{lang}/{namespace}.json (todos os 3 idiomas)
  2. Adicionar o namespace em TRANSLATION_NAMESPACES no SDK
  3. Importar no context/i18n.tsx do template
  4. Usar via useTranslation("namespace")