Auteur:
    Création:2025-11-20Dernière mise à jour:2026-06-23

    Traduisez votre site SvelteKit avec Intlayer | Internationalisation (i18n)

    ide.intlayer.org
    intlayer-sveltekit-template.vercel.app

    Table des matières

    Pourquoi Intlayer plutôt que des alternatives ?

    Par rapport aux solutions principales telles que svelte-i18n ou i18next, Intlayer est une solution dotée d'optimisations intégrées telles que :

    Intlayer est optimisé pour fonctionner parfaitement avec SvelteKit en offrant le routage multilingue, la prise en charge SSR et toutes les fonctionnalités nécessaires à la mise à l'échelle de l'internationalisation (i18n).

    Au lieu de charger de lourds fichiers JSON dans vos pages, ne chargez que le contenu strictement nécessaire. Intlayer vous aide à réduire la taille de votre bundle et de vos pages jusqu'à 50 %.

    Déclarer le contenu directement au plus près de vos composants facilite la maintenance des applications de grande envergure. Vous pouvez dupliquer ou supprimer le dossier d'une fonctionnalité sans le fardeau mental de devoir passer en revue toute votre base de code de contenu. De plus, Intlayer est entièrement typé pour garantir l'exactitude de vos traductions.

    La colocalisation du contenu réduit le contexte nécessaire aux grands modèles de langage (LLM). Intlayer est également livré avec une suite d'outils, tels qu'une CLI pour vérifier les traductions manquantes, un LSP, un MCP et des agent skills, afin de rendre l'expérience développeur (DX) encore plus fluide pour les agents IA.

    Automatisez les traductions dans votre pipeline CI/CD en utilisant le LLM de votre choix au coût de votre propre fournisseur d'IA. Intlayer propose également un compilateur pour automatiser l'extraction de contenu, ainsi qu'une plateforme web pour vous aider à traduire en arrière-plan.

    Associer de gros fichiers JSON à vos composants peut ralentir les performances et impacter la réactivité. Intlayer optimise le chargement du contenu directement au moment du build.

    Bien plus qu'une simple solution i18n, Intlayer propose un éditeur visuel auto-hébergé et un CMS complet pour gérer votre contenu multilingue en temps réel. Cela rend la collaboration avec les traducteurs, concepteurs-rédacteurs et autres membres de l'équipe extrêmement simple. Le contenu peut être stocké localement et/ou à distance.


    Guide étape par étape pour configurer Intlayer dans une application SvelteKit

    Voir Modèle d'application sur GitHub.

    Pour commencer, créez un nouveau projet SvelteKit. Voici la structure finale que nous allons réaliser :

    bash
    .
    ├── intlayer.config.ts
    ├── package.json
    ├── src
       ├── app.d.ts
    │   ├── app.html
    │   ├── hooks.server.ts
    │   ├── lib
    │   │   ├── getLocale.ts
    │   │   ├── LocaleSwitcher.svelte
    │   │   └── LocalizedLink.svelte
    │   ├── params
    │   │   └── locale.ts
    │   └── routes
    │       ├── [[locale=locale]]
    │       │   ├── +layout.svelte
    │       │   ├── +layout.ts
    │       │   ├── +page.svelte
    │       │   ├── +page.ts
    │       │   ├── about
    │       │   │   ├── +page.svelte
    │       │   │   ├── +page.ts
    │       │   │   └── page.content.ts
    │       │   ├── Counter.content.ts
    │       │   ├── Counter.svelte
    │       │   ├── Header.content.ts
    │       │   ├── Header.svelte
    │       │   ├── home.content.ts
    │       │   └── layout.content.ts
    │       ├── +layout.svelte
    │       └── layout.css
    ├── static
    │   ├── favicon.svg
    │   └── robots.txt
    ├── svelte.config.js
    ├── tsconfig.json
    └── vite.config.ts
    
    1. Installer les dépendances

      Installez les paquets nécessaires en utilisant npm :

      bash
      npx intlayer init --interactive
      
      l'indicateur --interactive est facultatif. Utilisez intlayer-cli init si vous êtes un agent IA.
      Cette commande détectera votre environnement et installera les packages requis. Par exemple :
      bash
      npm install intlayer svelte-intlayer
      npm install vite-intlayer --save-dev
      
      • intlayer : Le paquet principal pour l'internationalisation (i18n).
      • svelte-intlayer : Fournit des context providers et des stores pour Svelte/SvelteKit.
      • vite-intlayer : Le plugin Vite pour intégrer les déclarations de contenu dans le processus de build.
    2. Configuration de votre projet

      Créez un fichier de configuration à la racine de votre projet :

      intlayer.config.ts
      import { Locales, type IntlayerConfig } from "intlayer";
      
      const config: IntlayerConfig = {
        internationalization: {
          locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH],
          defaultLocale: Locales.ENGLISH,
        },
      };
      
      export default config;
      
    3. Intégrer Intlayer dans votre configuration Vite

      Mettez à jour votre fichier vite.config.ts pour inclure le plugin Intlayer. Ce plugin gère la transpilation de vos fichiers de contenu.

      vite.config.ts
      import { sveltekit } from "@sveltejs/kit/vite";
      import { defineConfig } from "vite";
      import { intlayer } from "vite-intlayer";
      
      export default defineConfig({
        plugins: [intlayer(), sveltekit()], // l'ordre est important, Intlayer doit être placé avant SvelteKit
      });
      
    4. Déclarez votre contenu

      Créez vos fichiers de déclaration de contenu n'importe où dans votre dossier src (par exemple, src/lib/content ou à côté de vos composants). Ces fichiers définissent le contenu traduisible pour votre application en utilisant la fonction t() pour chaque locale.

    5. Utilisez Intlayer dans vos composants

      Vous pouvez maintenant utiliser la fonction useIntlayer dans n'importe quel composant Svelte. Elle retourne un store réactif qui se met à jour automatiquement lorsque la locale change. La fonction respectera automatiquement la locale actuelle (à la fois lors du SSR et de la navigation côté client).

      pour accéder à sa valeur réactive (par exemple, $content.title).

      src/lib/components/Component.svelte
      <script lang="ts">
        import { useIntlayer } from "svelte-intlayer";
      
        // "hero-section" correspond à la clé définie à l'Étape 4
        const content = useIntlayer("hero-section");
      </script>
      
      <!-- Afficher le contenu comme contenu simple  -->
      <h1>{$content.title}</h1>
      <!-- Pour rendre le contenu éditable via l'éditeur -->
      <h1>{@const Title = $content.title}<Title /></h1>
      <!-- Pour afficher le contenu en tant que chaîne -->
      <div aria-label={$content.title.value}></div>
      <div aria-label={$content.title.toString()}></div>
      <div aria-label={String($content.title)}></div>
      
    6. Configurer le routage

      Facultatif

      Les étapes suivantes montrent comment configurer un routage basé sur la locale dans SvelteKit. Cela permet à vos URLs d'inclure le préfixe de la locale (par exemple, /en/about, /fr/about) pour un meilleur SEO et une meilleure expérience utilisateur.

      bash
      .
      └─── src
          ├── app.d.ts                  # Définir le type de la locale
          ├── hooks.server.ts           # Gérer le routage des locales
          ├── lib
          │   └── getLocale.ts          # Vérifier la locale depuis l'en-tête, les cookies
          ├── params
          │   └── locale.ts             # Définir le paramètre locale
          └── routes
              ├── [[locale=locale]]     # Encapsuler dans un groupe de routes pour définir la locale
              │   ├── +layout.svelte    # Mise en page locale pour la route
              │   ├── +layout.ts
              │   ├── +page.svelte
              │   ├── +page.ts
              │   └── about
              │       ├── +page.svelte
              │       └── +page.ts
              └── +layout.svelte         # Mise en page racine pour les polices et styles globaux
      
    7. Gérer la détection de la locale côté serveur

      Dans SvelteKit, le serveur doit connaître la locale de l'utilisateur pour rendre le contenu correct lors du SSR. Nous utilisons hooks.server.ts pour détecter la locale à partir de l'URL ou des cookies.

      Créez ou modifiez src/hooks.server.ts :

      src/hooks.server.ts
      import type { Handle } from "@sveltejs/kit";
      import { getLocalizedUrl } from "intlayer";
      import { getLocale } from "$lib/getLocale";
      
      export const handle: Handle = async ({ event, resolve }) => {
        const detectedLocale = getLocale(event);
      
        // Vérifie si le chemin actuel commence déjà par une locale (ex. /fr, /en)
        const pathname = event.url.pathname;
        const targetPathname = getLocalizedUrl(pathname, detectedLocale);
      
        // Si AUCUNE locale n'est présente dans l'URL (ex. l'utilisateur visite "/"), redirigez-le
        if (targetPathname !== pathname) {
          return new Response(undefined, {
            headers: { Location: targetPathname },
            status: 307, // Redirection temporaire
          });
        }
      
        return resolve(event, {
          transformPageChunk: ({ html }) => html.replace("%lang%", detectedLocale),
        });
      };
      

      Ensuite, créez un helper pour obtenir la locale de l'utilisateur à partir de l'événement de requête :

      src/lib/getLocale.ts
      import {
        configuration,
        getLocaleFromStorage,
        localeDetector,
        type Locale,
      } from "intlayer";
      import type { RequestEvent } from "@sveltejs/kit";
      
      /**
       * Récupère la locale de l'utilisateur à partir de l'événement de requête.
       * Cette fonction est utilisée dans le hook `handle` dans `src/hooks.server.ts`.
       *
       * Elle tente d'abord d'obtenir la locale depuis le stockage Intlayer (cookies ou en-têtes personnalisés).
       * Si la locale n'est pas trouvée, elle revient à la négociation "Accept-Language" du navigateur.
       *
       * @param event - L'événement de requête de SvelteKit
       * @returns La locale de l'utilisateur
       */
      export const getLocale = (event: RequestEvent): Locale => {
        const defaultLocale = configuration?.internationalization?.defaultLocale;
      
        // Tente d'obtenir la locale depuis le stockage Intlayer (cookies ou en-têtes)
        const storedLocale = getLocaleFromStorage({
          // Accès aux cookies SvelteKit
          getCookie: (name: string) => event.cookies.get(name) ?? null,
          // Accès aux headers SvelteKit
          getHeader: (name: string) => event.request.headers.get(name) ?? null,
        });
      
        if (storedLocale) {
          return storedLocale;
        }
      
        // Repli sur la négociation "Accept-Language" du navigateur
        const negotiatorHeaders: Record<string, string> = {};
      
        // Conversion de l'objet Headers de SvelteKit en un Record<string, string> simple
        event.request.headers.forEach((value, key) => {
          negotiatorHeaders[key] = value;
        });
      
        // Vérification de la locale à partir du header `Accept-Language`
        const userFallbackLocale = localeDetector(negotiatorHeaders);
      
        if (userFallbackLocale) {
          return userFallbackLocale;
        }
      
        // Retourne la locale par défaut si aucune correspondance n'est trouvée
        return defaultLocale;
      };
      
      getLocaleFromStorage vérifiera la locale à partir de l'en-tête ou du cookie selon votre configuration. Voir Configuration pour plus de détails.
      La fonction localeDetector traitera l'en-tête Accept-Language et retournera la meilleure correspondance.

      Si la locale n'est pas configurée, nous souhaitons retourner une erreur 404. Pour faciliter cela, nous pouvons créer une fonction match pour vérifier si la locale est valide :

      /src/params/locale.ts
      export const match = (param: Locale = defaultLocale): boolean =>
        locales.includes(param);
      

      Note : Assurez-vous que votre fichier src/app.d.ts inclut la définition de la locale :

      typescript
      declare global {
        namespace App {
          interface Locals {
            locale: import("intlayer").Locale;
          }
        }
      }
      

      Pour le fichier +layout.svelte, nous pouvons tout supprimer afin de ne conserver que le contenu statique, non lié à l’i18n :

      src/+layout.svelte
      <script lang="ts">
           import './layout.css';
      
          let { children } = $props();
      </script>
      
      <div class="app">
          {@render children()}
      </div>
      
      <style>
          .app {
          /*  */
          }
      </style>
      

      Ensuite, créez une nouvelle page et un layout sous le groupe [[locale=locale]] :

      src/routes/[[locale=locale]]/+layout.ts
      import type { Load } from "@sveltejs/kit";
      import { defaultLocale, type Locale } from "intlayer";
      
      export const prerender = true;
      
      // Utilisez le type générique Load
      export const load: Load = ({ params }) => {
        const locale: Locale = (params.locale as Locale) ?? defaultLocale;
      
        return {
          locale,
        };
      };
      
      src/routes/[[locale=locale]]/+layout.svelte
      <script lang="ts">
          import type { Snippet } from 'svelte';
          import { useIntlayer, setupIntlayer } from "svelte-intlayer";
          import Header from './Header.svelte';
          import type { LayoutData } from './$types';
      
          let { children, data }: { children: Snippet, data: LayoutData } = $props();
      
          // Initialiser Intlayer avec la locale provenant de la route
        $effect(() => {
            setupIntlayer(data.locale);
        });
          // Utiliser le dictionnaire de contenu du layout
          const layoutContent = useIntlayer('layout');
      </script>
      
      <Header />
      
      <main>
          {@render children()}
      </main>
      
      <footer>
          <p>
              {$layoutContent.footer.prefix.value}{' '}
              <a href="https://svelte.dev/docs/kit">{$layoutContent.footer.linkLabel.value}</a>{' '}
              {$layoutContent.footer.suffix.value}
          </p>
      </footer>
      
      <style>
        /*  */
      </style>
      
      src/routes/[[locale=locale]]/+page.ts
      export const prerender = true;
      
      src/routes/[[locale=locale]]/+page.svelte
      <script lang="ts">
          import { useIntlayer } from "svelte-intlayer";
      
          // Utiliser le dictionnaire de contenu de la page d'accueil
          const homeContent = useIntlayer('home');
      </script>
      
      <svelte:head>
          <title>{$homeContent.title.value}</title>
      </svelte:head>
      
      <section>
          <h1>
              {$homeContent.title}
          </h1>
      </section>
      
      <style>
        /*  */
      </style>
      
    8. Liens internationalisés

      Facultatif

      Pour le SEO, il est recommandé de préfixer vos routes avec la locale (par exemple, /en/about, /fr/about). Ce composant préfixe automatiquement tout lien avec la locale courante.

      src/lib/components/LocalizedLink.svelte
      <script lang="ts">
        import { getLocalizedUrl } from "intlayer";
        import { useLocale } from "svelte-intlayer";
      
        let { href = "" } = $props();
        const { locale } = useLocale();
      
        // Aide pour préfixer l'URL avec la locale courante
        $: localizedHref = getLocalizedUrl(href, $locale);
      </script>
      
      <a href={localizedHref}>
        <slot />
      </a>
      

      Si vous utilisez goto de SvelteKit, vous pouvez utiliser la même logique avec getLocalizedUrl pour naviguer vers l'URL localisée :

      typescript
      import { goto } from "$app/navigation";
      import { getLocalizedUrl } from "intlayer";
      import { useLocale } from "svelte-intlayer";
      
      const { locale } = useLocale();
      const localizedPath = getLocalizedUrl("/about", $locale);
      goto(localizedPath); // Navigue vers /en/about ou /fr/about selon la locale
      
    9. Sélecteur de langue

      Facultatif

      Pour permettre aux utilisateurs de changer de langue, mettez à jour l’URL.

      src/lib/components/LanguageSwitcher.svelte
      <script lang="ts">
        import { getLocalizedUrl, getLocaleName } from 'intlayer';
        import { useLocale } from "svelte-intlayer";
        import { page } from '$app/stores';
        import { goto } from '$app/navigation';
      
        const { locale, setLocale, availableLocales } = useLocale({
          onLocaleChange: (newLocale) => {
            const localizedPath = getLocalizedUrl($page.url.pathname, newLocale);
            goto(localizedPath);
          },
        });
      </script>
      
      <ul class="locale-list">
        {#each availableLocales as localeEl}
          <li>
            <a
              href={getLocalizedUrl($page.url.pathname, localeEl)}
              onclick={(e) => {
                e.preventDefault();
                setLocale(localeEl); // Va définir la locale dans le store et déclencher onLocaleChange
              }}
              class:active={$locale === localeEl}
            >
              {getLocaleName(localeEl)}
            </a>
          </li>
        {/each}
      </ul>
      
      <style>
        /* */
      </style>
      
    10. Ajouter un proxy backend

      Facultatif

      Pour ajouter un proxy backend à votre application SvelteKit, vous pouvez utiliser la fonction intlayerProxy fournie par le plugin vite-intlayer. Ce plugin détectera automatiquement la meilleure locale pour l'utilisateur en fonction de l'URL, des cookies et des préférences linguistiques du navigateur.

      Depuis Intlayer v9, intlayerProxy() est fourni directement dans le plugin intlayer() et activé par défaut via l'option routing.enableProxy (true par défaut). L'enregistrement séparé comme indiqué ci-dessous est désormais optionnel — il est conservé pour la compatibilité rétroactive et les configurations qui nécessitent de contrôler l'ordre des plugins. Définissez routing.enableProxy: false pour désactiver cette fonctionnalité. Consultez les notes de version v9.
      vite.config.ts
      import { defineConfig } from "vite";
      import { intlayer } from "vite-intlayer";
      import { sveltekit } from "@sveltejs/kit/vite";
      
      // https://vitejs.dev/config/
      export default defineConfig({
        plugins: [
          intlayer({
            proxy: {
              ignore: (req) => req.url?.startsWith("/api"),
            },
          }),
          sveltekit(),
        ],],
      });
      
    11. Configurer l'éditeur / CMS intlayer

      Facultatif

      Pour configurer l'éditeur intlayer, vous devez suivre la documentation de l'éditeur intlayer.

      Pour configurer le CMS intlayer, vous devez suivre la documentation du CMS intlayer.

      Pour pouvoir visualiser le sélecteur de l'éditeur intlayer, vous devrez utiliser la syntaxe composant dans votre contenu intlayer.

      Component.svelte
      <script lang="ts">
        import { useIntlayer } from "svelte-intlayer";
      
        const content = useIntlayer("component");
      </script>
      
      <div>
      
        <!-- Rendre le contenu comme contenu simple -->
        <h1>{$content.title}</h1>
      
        <!-- Rendre le contenu comme un composant (requis par l'éditeur) -->
        {@const Component = $content.component}<Component />
      </div>
      
    12. Extraire le contenu de vos composants

      Facultatif

      Si vous avez une base de code existante, transformer des milliers de fichiers peut prendre beaucoup de temps.

      Pour faciliter ce processus, Intlayer propose un compilateur / extracteur pour transformer vos composants et extraire le contenu.

      Pour le configurer, vous pouvez ajouter une section compiler dans votre fichier intlayer.config.ts :

      intlayer.config.ts
      import { type IntlayerConfig } from "intlayer";
      
      const config: IntlayerConfig = {
        // ... Reste de votre configuration
        compiler: {
          /**
           * Indique si le compilateur doit être activé.
           */
          enabled: true,
      
          /**
           * Définit le chemin des fichiers de sortie
           */
          output: ({ fileName, extension }) => `./${fileName}${extension}`,
      
          /**
           * Indique si les composants doivent être sauvegardés après avoir été transformés. De cette façon, le compilateur peut être exécuté une seule fois pour transformer l'application, puis il peut être supprimé.
           */
          saveComponents: false,
      
          /**
           * Préfixe de clé de dictionnaire
           */
          dictionaryKeyPrefix: "",
        },
      };
      
      export default config;
      

      Exécutez l'extracteur pour transformer vos composants et extraire le contenu

      bash
      npx intlayer extract
      
      Since v9, the intlayerCompiler is included in the intlayer plugin. So you don't need to add it manually.

      Mettez à jour votre fichier vite.config.ts pour inclure le plugin intlayerCompiler :

      vite.config.ts
      import { defineConfig } from "vite";
      import { intlayer, intlayerCompiler } from "vite-intlayer";
      
      export default defineConfig({
        plugins: [
          intlayer(),
          intlayerCompiler(), // Adds the compiler plugin
        ],
      });
      
      bash
      npm run build # Ou npm run dev
      

    Configuration Git

    Il est recommandé d'ignorer les fichiers générés par Intlayer.

    .gitignore
    # Ignorer les fichiers générés par Intlayer
    .intlayer
    

    Aller plus loin

    • Éditeur Visuel : Intégrez l'Éditeur Visuel Intlayer pour éditer les traductions directement depuis l'interface utilisateur.
    • CMS : Externalisez la gestion de votre contenu en utilisant le CMS Intlayer.