Documentação

Internacionalização

Como o Motoko Base gerencia locales, roteamento, catálogos de mensagens e SEO para produtos SaaS multilíngues.

Abrir emChatGPT (abre em uma nova aba)Claude (abre em uma nova aba)Cursor (abre em uma nova aba)Como o Motoko Base gerencia locales, roteamento, catálogos de mensagens e SEO para produtos SaaS multilíngues.

O Motoko Base inclui uma base de internacionalização (i18n) completa construída com next-intl. Você obtém cinco locales, URLs de marketing com suporte a locale, shell do dashboard traduzido, documentação e changelog localizados, e um padrão claro para estender traduções aos seus próprios recursos.

Esta página explica como a i18n está integrada. Para instruções passo a passo ao adicionar copy, veja Adicionar traduções.

Locales suportados

LocaleCódigoPrefixo URL marketingExemplo
Inglês (padrão)en(nenhum)/, /docs, /terms
Espanholes/es/es/docs, /es/terms
Alemãode/de/de/docs
Francêsfr/fr/fr/docs
Português brasileiropt-BR/pt-br/pt-br/docs

As definições de locale ficam em src/i18n/routing.ts. Os rótulos do seletor de idioma vêm de localeLabels no mesmo arquivo.

Modelo de roteamento híbrido

O Motoko Base usa duas estratégias de roteamento de propósito:

Superfícies com prefixo de locale (marketing)

Essas rotas ficam em src/app/[locale]/:

  • Landing page e seções de marketing
  • Páginas legais (/terms, /privacy, /licence)
  • Documentação (/docs)
  • Changelog (/changelog)

O inglês usa URLs sem prefixo (localePrefix: 'as-needed'). Outros locales recebem um prefixo (/fr, /de, /es, /pt-br).

O seletor de idioma de marketing (MarketingLanguageSwitcher) navega entre caminhos equivalentes em cada locale mantendo o contexto da página.

Superfícies do app sem prefixo

Essas rotas permanecem em caminhos fixos sem segmento de locale:

  • Dashboard e recursos demo (/dashboard/...)
  • Fluxos de autenticação (/sign-in, /sign-up, esqueci/redefinir/verificar)
  • Rotas API, webhooks, redirects públicos (/api, /r/[slug])

O locale ativo é resolvido no momento da requisição — não pela URL.

Resolução de locale

Quando o next-intl precisa de um locale, src/i18n/resolve-locale.ts aplica esta prioridade:

Usuário autenticado  →  user_preferences.language (banco de dados)
Visitante            →  cookie NEXT_LOCALE
Fallback             →  cabeçalho Accept-Language
Padrão               →  en

Primeira visita a /: src/proxy.ts lê Accept-Language uma vez. Se corresponder a um locale suportado diferente do inglês, redireciona para a URL de marketing com prefixo e define o cookie. Depois, escolhas explícitas (seletor ou Configurações) prevalecem.

Usuários autenticados: salvar o idioma em Configurações → App → Aparência (/dashboard/settings/app/appearance) atualiza o banco via updateLanguagePreferenceAction, define o cookie e atualiza a UI via LocalePreferenceSync.

Estrutura de arquivos

src/i18n/
├── routing.ts          # Locales, prefixos, nome do cookie
├── navigation.ts       # Link, useRouter, usePathname com locale
├── request.ts          # Config servidor next-intl
├── resolve-locale.ts   # Resolução para rotas app/auth
├── load-messages.ts    # Import dinâmico de catálogos
└── fumadocs.ts         # Locales de conteúdo docs/changelog

messages/{locale}/      # Namespaces JSON por recurso
content/docs/           # MDX localizado via sufixo dot
content/changelog/

Helpers de formatação compartilhados em src/lib/i18n/format.ts. Use-os em vez de hardcodar "en-US" em chamadas Intl.

Catálogos de mensagens

Traduções são namespaces JSON tipados em messages/{locale}/. Use um namespace por recurso ou área (auth, settings, …). Mantenha keys estáveis em todos os locales.

Marketing: estrutura vs copy

CamadaLocalContém
Estruturasrc/features/marketing/marketing-structure.tsIDs, hrefs, refs tech, ordem
Copymessages/{locale}/marketing.jsonTítulos, descrições, FAQ

Usar traduções em componentes

Componentes cliente

"use client";
import { useTranslations } from "next-intl";

export function MyPage() {
  const t = useTranslations("overview");
  return <h1>{t("welcome.title", { name: "Alex" })}</h1>;
}

Servidor e metadata

import { getTranslations } from "next-intl/server";

Importe de @/i18n/navigation — não next/link — em páginas com prefixo de locale.

Docs e changelog localizados

Conteúdo Fumadocs com parser dot (page.de.mdx, …). Inglês é o arquivo base.

SEO

URLs localizadas recebem canonicals por locale, alternates hreflang e entradas no sitemap.


Próximos passos

Adicionar traduções — Guia prático.

Estrutura do projeto — Onde fica o código.

Configuração — Nav do dashboard e config do produto.