Skip to main content

i18n SvelteKit : guide de configuration de l'internationalisation

De zéro au multilingue : configurez svelte-i18n dans votre application SvelteKit avec le format de message ICU, le routage par langue et des chaînes de repli intelligentes.

1

Installer svelte-i18n

svelte-i18n est la bibliothèque standard d'internationalisation pour Svelte et SvelteKit. Elle offre des stores réactifs, la prise en charge du format ICU MessageFormat et le chargement différé des langues, prêts à l'emploi.

svelte-i18n utilise le format ICU MessageFormat pour les pluriels et les variables, la même norme que celle utilisée par FormatJS/react-intl. Si vous venez de React, la syntaxe des messages vous sera familière.
Terminal
npm install svelte-i18n
2

Configurer svelte-i18n

Créez un fichier de configuration i18n qui enregistre vos langues avec des fonctions d'import à chargement différé. svelte-i18n ne récupère les messages d'une langue que lorsque celle-ci est activée.

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
});
Vous devez importer votre fichier de configuration i18n dans +layout.svelte avant le rendu de tout composant. Si les traductions affichent des clés brutes comme « nav.home », c'est que la configuration n'a pas été importée assez tôt.

Intégration au layout SvelteKit

Importez votre configuration i18n dans le layout racine et protégez le rendu à l'aide du store $isLoading. Cela évite un affichage de clés non traduites pendant le chargement asynchrone des données de langue.

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}

Routage basé sur la locale dans SvelteKit

Pour des URL conviviales pour le référencement comme /en/about et /de/about, utilisez un paramètre de route [lang]. Définissez la locale de svelte-i18n dans la fonction load du layout en fonction du paramètre d'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}

Format des fichiers de traduction

Créez un fichier JSON par locale. svelte-i18n prend en charge les clés imbriquées ainsi que la syntaxe ICU MessageFormat pour les pluriels, les variables et les expressions 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}}"
  }
}
Nommez les clés d'après ce qu'elles décrivent, et non l'endroit où elles apparaissent : 'cart.itemCount' est préférable à 'homepageCartLabel'. Les clés doivent survivre aux refontes de l'interface.
3

Utiliser les traductions dans les composants

Importez le store $_ (ou $format) depuis svelte-i18n et utilisez-le dans vos modèles Svelte. Ce store est réactif : lorsque la locale change, toutes les chaînes traduites se mettent à jour automatiquement.

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>
$_ est un store Svelte : vous devez utiliser le préfixe $ dans les modèles. Écrire _('key') sans le signe dollar renvoie l'objet store, et non la chaîne traduite.

Changement de langue

Créez un sélecteur de langue lié au store $locale. Lorsque la valeur change, svelte-i18n charge les messages de la nouvelle locale et met à jour de façon réactive toutes les chaînes traduites.

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

Gérer les pluriels avec ICU MessageFormat

svelte-i18n utilise ICU MessageFormat pour la gestion des pluriels : la norme internationale qui prend en charge toutes les catégories de pluriel CLDR. L'arabe compte 6 formes, le russe 4, le japonais 1. Définissez les formes dont vos langues cibles ont besoin et svelte-i18n sélectionne automatiquement la bonne.

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 {#個のアイテム}}"
}
Ne codez jamais en dur la logique singulier/pluriel dans vos composants. Des langues comme le français considèrent 0 comme singulier. L'arabe, le russe et le polonais possèdent des formes plurielles que l'anglais n'a pas. Laissez la syntaxe plural d'ICU s'en charger.

Solutions de repli intelligentes pour les locales avec svelte-i18n-locale-chain

svelte-i18n bascule directement vers fallbackLocale lorsqu'une clé est manquante : il n'existe aucun repli intermédiaire. Un utilisateur pt-BR voit s'afficher de l'anglais au lieu de traductions pt-PT parfaitement valables. svelte-i18n-locale-chain corrige cela grâce à des chaînes de repli intelligentes qui fusionnent en profondeur les messages des variantes régionales.

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 gère en interne l'ensemble du chargement des messages. N'utilisez pas la fonction register() de svelte-i18n en parallèle : initLocaleChain se charge de l'enregistrement, du chargement et de la fusion en profondeur.

Automatiser les traductions

Une fois votre configuration i18n terminée, traduisez vos fichiers de locale à l'aide de l'IA. Dans votre IDE, demandez à votre assistant IA de traduire votre fichier source, ou utilisez l'outil CLI i18n Agent dans votre pipeline 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
Traduisez de façon incrémentale : lorsque vous ajoutez de nouvelles clés à votre fichier source, ne traduisez que les différences plutôt que de régénérer tous les fichiers. Cela préserve les traductions déjà relues par un humain.

Automatiser la qualité des traductions

Détectez les clés manquantes et les espaces réservés cassés avant leur mise en production grâce à i18n-validate. Testez votre interface avec des pseudo-traductions grâce à i18n-pseudo avant l'arrivée des traductions réelles.

Pièges courants

Fuite de locale en SSR dans SvelteKit

Les stores svelte-i18n sont des singletons. En SSR avec SvelteKit, les requêtes concurrentes partagent le même store : la locale d'un utilisateur peut se retrouver dans la réponse d'un autre. Solution : appelez locale.set() dans le hook handle ou dans la fonction load du layout, afin que chaque requête reçoive le bon contexte de locale.

Utiliser register() avec svelte-i18n-locale-chain

N'utilisez pas la fonction register() de svelte-i18n si vous utilisez svelte-i18n-locale-chain. initLocaleChain gère en interne l'ensemble du chargement des messages. Combiner les deux entraîne un chargement de messages en double ou en conflit.

Les erreurs de syntaxe ICU échouent silencieusement

Une accolade mal appariée ou une catégorie de pluriel manquante dans une chaîne ICU MessageFormat provoque des échecs silencieux : la chaîne de message brute s'affiche au lieu du résultat formaté. Validez la syntaxe ICU dans votre pipeline CI.

Flash de contenu non traduit

Si vous affichez des composants avant la fin du chargement des traductions, les utilisateurs voient les clés brutes. Protégez votre layout avec {#if $isLoading}...{:else}...{/if} pour afficher un état de chargement jusqu'à ce que les messages soient prêts.

Structure de fichiers recommandée

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

Essayez i18n Agent maintenant

Déposez votre fichier de traduction ici

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

ou cliquez pour parcourir

Langues cibles

Aucune inscription requiseEstimation instantanée

Repli de locale avec svelte-i18n-locale-chain

Lorsqu'une clé de traduction est manquante dans une locale régionale comme pt-BR, svelte-i18n bascule directement vers la locale par défaut au lieu de vérifier d'abord la locale parente 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',
});

Consultez notre guide de repli de locale pour découvrir la liste complète des frameworks pris en charge et les 75 chaînes intégrées. Learn more →

Questions fréquentes