Skip to main content

i18n em SvelteKit: guia de configuração da internacionalização

De um idioma a vários: configure svelte-i18n na sua aplicação SvelteKit com o formato de mensagens ICU, roteamento regional e cadeias de fallback inteligentes.

1

Instalar svelte-i18n

svelte-i18n é a biblioteca padrão de internacionalização para Svelte e SvelteKit. Oferece nativamente stores reativos, compatibilidade com ICU MessageFormat e carregamento diferido de localidades.

svelte-i18n utiliza ICU MessageFormat para plurais e variáveis, a mesma norma de FormatJS/react-intl. Se vier do React, reconhecerá a sintaxe das mensagens.
Terminal
npm install svelte-i18n
2

Configurar svelte-i18n

Crie um arquivo de configuração de i18n que registre suas localidades através de funções de importação com carregamento diferido. svelte-i18n só obtém as mensagens de uma localidade quando esta é ativada.

src/lib/i18n.ts
// src/lib/i18n.ts
import { register, init, getLocaleFromNavigator } from 'svelte-i18n';

// Register locale loaders (lazy-loaded)
register('en', () => import('../locales/en.json'));
register('de', () => import('../locales/de.json'));
register('ja', () => import('../locales/ja.json'));
register('es', () => import('../locales/es.json'));

init({
  fallbackLocale: 'en',
  initialLocale: getLocaleFromNavigator(),  // Auto-detect browser language
});
Deve importar o arquivo de configuração de i18n em +layout.svelte antes de qualquer componente ser apresentado. Se as traduções mostrarem chaves em bruto, como 'nav.home', a configuração não foi importada suficientemente cedo.

Integração no layout do SvelteKit

Importe a configuração de i18n no layout de raiz e proteja a apresentação com o store $isLoading. Assim evita a aparição momentânea de chaves não traduzidas enquanto os dados regionais são carregados assincronamente.

src/routes/+layout.svelte
<!-- src/routes/+layout.svelte -->
<script>
  // Import i18n config — must run before any component renders
  import '../lib/i18n';
  import { isLoading } from 'svelte-i18n';
</script>

{#if $isLoading}
  <p>Loading translations...</p>
{:else}
  <slot />
{/if}

Roteamento regional no SvelteKit

Para URLs favoráveis a SEO, como /en/about e /de/about, utilize um parâmetro de rota [lang]. Defina a localidade de svelte-i18n na função load do layout com base no parâmetro da URL.

SvelteKit locale routing
// src/routes/[lang]/+layout.ts
import { locale } from 'svelte-i18n';

export function load({ params }) {
  // Set the active locale from the URL parameter
  locale.set(params.lang);
  return {};
}

// src/routes/[lang]/+layout.svelte
<script>
  import '../../lib/i18n';
  import { isLoading } from 'svelte-i18n';
</script>

{#if $isLoading}
  <p>Loading...</p>
{:else}
  <slot />
{/if}

Formato dos arquivos de tradução

Crie um arquivo JSON por localidade. svelte-i18n aceita chaves aninhadas e sintaxe ICU MessageFormat para plurais, variáveis e expressões select.

Translation files
// src/locales/en.json
{
  "nav": {
    "home": "Home",
    "about": "About",
    "settings": "Settings"
  },
  "greeting": "Hello, {name}!",
  "cart": {
    "itemCount": "{count, plural, one {# item} other {# items}}"
  }
}

// src/locales/de.json
{
  "nav": {
    "home": "Startseite",
    "about": "Uber uns",
    "settings": "Einstellungen"
  },
  "greeting": "Hallo, {name}!",
  "cart": {
    "itemCount": "{count, plural, one {# Artikel} other {# Artikel}}"
  }
}
Dê às chaves nomes que descrevam o conteúdo, não o local onde aparece: 'cart.itemCount' é melhor do que 'homepageCartLabel'. As chaves devem sobreviver a alterações na interface.
3

Utilizar traduções nos componentes

Importe o store $_ —ou $format— de svelte-i18n e utilize-o nos modelos Svelte. O store é reativo: quando a localidade muda, todas as strings traduzidas são atualizadas automaticamente.

Component.svelte
<script>
  import { _ } from 'svelte-i18n';
</script>

<h1>{$_('greeting', { values: { name: 'World' } })}</h1>

<nav>
  <a href="/">{$_('nav.home')}</a>
  <a href="/about">{$_('nav.about')}</a>
</nav>
Formatting helpers
<script>
  import { _, date, number, time } from 'svelte-i18n';
</script>

<!-- Simple string -->
<p>{$_('greeting', { values: { name: userName } })}</p>

<!-- ICU plurals — handled automatically -->
<p>{$_('cart.itemCount', { values: { count: 3 } })}</p>

<!-- Date formatting -->
<p>{$date(new Date(), { format: 'long' })}</p>

<!-- Number formatting -->
<p>{$number(1999.99, { style: 'currency', currency: 'USD' })}</p>
$_ é um store Svelte: deve utilizar o prefixo $ nos modelos. Escrever _('key') sem o cifrão devolve o objeto store, não a string traduzida.

Selecionar o idioma

Crie um seletor de idioma ligado ao store $locale. Quando o valor muda, svelte-i18n carrega as mensagens da nova localidade e atualiza reativamente todas as strings traduzidas.

LanguageSwitcher.svelte
<script>
  import { locale, locales } from 'svelte-i18n';

  const LANGUAGE_NAMES = {
    en: 'English',
    de: 'Deutsch',
    ja: '日本語',
    es: 'Espanol',
  };
</script>

<select bind:value={$locale}>
  {#each $locales as loc}
    <option value={loc}>{LANGUAGE_NAMES[loc] ?? loc}</option>
  {/each}
</select>
4

Tratar plurais com ICU MessageFormat

svelte-i18n utiliza ICU MessageFormat na pluralização, a norma internacional que trata todas as categorias CLDR. O árabe tem 6 formas, o russo 4 e o japonês 1. Defina as formas necessárias e svelte-i18n seleciona automaticamente a correta.

ICU plural forms by language
// svelte-i18n uses ICU MessageFormat for plurals
// English:
{
  "items": "{count, plural, one {# item} other {# items}}"
}

// Arabic (6 forms):
{
  "items": "{count, plural, zero {no items} one {item} two {two items} few {# items} many {# items} other {# items}}"
}

// Japanese (1 form):
{
  "items": "{count, plural, other {#個のアイテム}}"
}
Nunca codifique diretamente lógica de singular/plural nos componentes. Idiomas como o francês consideram 0 singular. O árabe, russo e polonês têm formas inexistentes em inglês. Deixe a sintaxe de plural ICU tratar do assunto.

Fallbacks regionais inteligentes com svelte-i18n-locale-chain

svelte-i18n recorre diretamente a fallbackLocale quando falta uma chave: não existe um fallback intermediário. Um usuário pt-BR vê inglês em vez de traduções pt-PT válidas. svelte-i18n-locale-chain corrige isso com cadeias inteligentes que combinam profundamente mensagens de variantes regionais.

Terminal
npm install svelte-i18n-locale-chain svelte-i18n
src/lib/i18n.ts
// src/lib/i18n.ts
import { initLocaleChain, setLocale } from 'svelte-i18n-locale-chain';

// Replace svelte-i18n's init + register with initLocaleChain
await initLocaleChain({
  loadMessages: (locale) =>
    import(`../locales/${locale}.json`).then(m => m.default),
  defaultLocale: 'en',
  initialLocale: 'pt-BR',
});

// Later, to change locale:
await setLocale('fr-CA');
// fr-CA user sees: fr-CA messages -> fr messages -> en messages
// No missing keys — deep-merged automatically
svelte-i18n-locale-chain gerencia internamente todo o carregamento das mensagens. Não utilize em simultâneo a função register() de svelte-i18n: initLocaleChain trata do cadastro, carregamento e combinação profunda.

Automatizar as traduções

Depois de concluir a configuração de i18n, traduza os arquivos de localidade com IA. No IDE, peça ao assistente para traduzir o arquivo de origem ou utilize a CLI do i18n Agent no seu pipeline de CI/CD.

Terminal
# In your IDE, ask your AI assistant:
> Translate src/locales/en.json to German, Japanese, and Spanish

✓ de.json created (1.2s)
✓ ja.json created (1.5s)
✓ es.json created (1.1s)

# Or use the CLI in CI/CD:
npx i18n-agent translate src/locales/en.json --lang de,ja,es
Traduza de forma incremental: quando adicionar novas chaves ao arquivo de origem, traduza apenas as diferenças em vez de gerar novamente todos os arquivos. Assim preserva as traduções revisadas por pessoas.

Automatizar a qualidade das traduções

Detecte chaves em falta e marcadores danificados antes da publicação com i18n-validate. Teste a interface com pseudotraduções através de i18n-pseudo antes de chegarem as traduções reais.

Erros frequentes

Contaminação regional em SSR do SvelteKit

Os stores de svelte-i18n são singletons. Em SSR do SvelteKit, as requisições simultâneas compartilham o mesmo store, por isso a localidade de um usuário pode contaminar a resposta de outro. Solução: chame locale.set() no hook handle ou na função load do layout para cada requisição receber o contexto correto.

Utilizar register() com svelte-i18n-locale-chain

Não utilize register() de svelte-i18n se estiver utilizando svelte-i18n-locale-chain. initLocaleChain trata internamente de todo o carregamento. Misturar ambos provoca carregamentos duplicados ou em conflito.

Os erros de sintaxe ICU falham silenciosamente

Uma chaveta sem par ou uma categoria de plural em falta nas strings ICU MessageFormat provoca falhas silenciosas: é apresentada a mensagem em bruto em vez do resultado formatado. Valide a sintaxe ICU no pipeline de CI.

Aparição momentânea de conteúdo não traduzido

Se apresentar componentes antes de terminar o carregamento das traduções, os usuários veem chaves em bruto. Proteja o layout com {#if $isLoading}...{:else}...{/if} para mostrar um estado de carregamento até as mensagens estarem prontas.

Estrutura de arquivos recomendada

Project Structure
my-sveltekit-app/
├── src/
│   ├── lib/
│   │   └── i18n.ts              # i18n configuration
│   ├── locales/
│   │   ├── en.json              # Source language
│   │   ├── de.json              # German
│   │   ├── ja.json              # Japanese
│   │   └── es.json              # Spanish
│   └── routes/
│       ├── +layout.svelte       # Import i18n, guard isLoading
│       ├── +page.svelte
│       └── [lang]/              # Optional: locale-based routing
│           ├── +layout.ts       # Set locale from URL param
│           ├── +layout.svelte
│           └── +page.svelte
├── svelte.config.js
└── package.json

Experimente já o i18n Agent

Solte aqui seu arquivo de tradução

JSON, YAML, PO, XML, CSV, Markdown, Properties

ou clique para selecionar

Idiomas de destino

Sem cadastroEstimativa imediata

Fallback regional com svelte-i18n-locale-chain

Quando falta uma chave de tradução em uma localidade como pt-BR, svelte-i18n passa diretamente para a localidade predefinida em vez de verificar primeiro a localidade principal pt.

Terminal
npm install svelte-i18n-locale-chain
Configuration
import { initLocaleChain } from 'svelte-i18n-locale-chain';

initLocaleChain({
  fallbacks: {
    'pt-BR': ['pt', 'en'],
    'zh-Hant-HK': ['zh-Hant', 'zh', 'en'],
  },
  defaultLocale: 'en',
});

Consulte nosso guia de fallback regional para ver a lista completa de frameworks compatíveis e as 75 cadeias integradas. Learn more →

Perguntas frequentes