Creation:2026-04-02Last update:2026-04-02

    Domaines personnalisés

    Intlayer prend en charge le routage par domaine, vous permettant de servir des locales spécifiques à partir de noms d'hôte dédiés. Par exemple, les visiteurs chinois peuvent être dirigés vers intlayer.zh au lieu de intlayer.org/zh.

    Fonctionnement

    La carte domains dans routing associe chaque locale à un nom d'hôte. Intlayer utilise cette carte à deux endroits :

    1. Génération d'URL (getLocalizedUrl) : lorsque la locale cible se trouve sur un domaine différent de la page actuelle, une URL absolue est retournée (ex: https://intlayer.zh/about). Lorsque les deux domaines correspondent, une URL relative est retournée (ex: /fr/about).
    2. Proxy serveur (Next.js & Vite) : les requêtes entrantes sont redirigées ou réécrites en fonction du domaine sur lequel elles arrivent.

    Domaines exclusifs vs partagés

    La distinction clé est l'exclusivité :

    • Domaine exclusif - une seule locale correspond à ce nom d'hôte (ex: zh → intlayer.zh). Le domaine lui-même identifie la locale, donc aucun préfixe de locale n'est ajouté au chemin. https://intlayer.zh/about sert le contenu chinois.
    • Domaine partagé - plusieurs locales correspondent au même nom d'hôte (ex: en et fr correspondent tous deux à intlayer.org). Le routage standard basé sur les préfixes s'applique. intlayer.org/fr/about sert le contenu français.

    Configuration

    intlayer.config.ts
    import { Locales, type IntlayerConfig } from "intlayer";const config: IntlayerConfig = {  internationalization: {    locales: [      Locales.ENGLISH,      Locales.FRENCH,      Locales.SPANISH,      Locales.CHINESE,    ],    defaultLocale: Locales.ENGLISH,  },  routing: {    mode: "prefix-no-default",    domains: {      // Domaine partagé - en et fr utilisent le routage par préfixe sur intlayer.org      en: "intlayer.org",      // Domaine exclusif - zh a son propre nom d'hôte, aucun préfixe /zh/ n'est nécessaire      zh: "intlayer.zh",    },  },};export default config;

    Les locales qui ne sont pas listées dans domains continuent d'utiliser le routage par préfixe standard sans aucune substitution de domaine.

    Génération d'URL

    getLocalizedUrl produit automatiquement le bon type d'URL en fonction du contexte d'appel.

    Locale sur le même domaine (URL relative)

    ts
    // Page actuelle : intlayer.org/aboutgetLocalizedUrl("/about", "fr", { currentDomain: "intlayer.org" });// → "/fr/about"getLocalizedUrl("/about", "en", { currentDomain: "intlayer.org" });// → "/about"  (locale par défaut, pas de préfixe)

    Locale sur un domaine différent (URL absolue)

    ts
    // Page actuelle : intlayer.org/aboutgetLocalizedUrl("/about", "zh", { currentDomain: "intlayer.org" });// → "https://intlayer.zh/about"  (domaine exclusif, pas de préfixe /zh/)

    Service depuis le propre domaine de la locale

    ts
    // Page actuelle : intlayer.zh/aboutgetLocalizedUrl("/about", "zh", { currentDomain: "intlayer.zh" });// → "/about"  (déjà sur le bon domaine - URL relative)getLocalizedUrl("/about", "fr", { currentDomain: "intlayer.zh" });// → "https://intlayer.org/fr/about"  (lien inter-domaines vers intlayer.org)

    Auto-détection du domaine actuel

    currentDomain est facultatif. S'il est omis, getLocalizedUrl le résout dans cet ordre :

    1. Le nom d'hôte d'une URL d'entrée absolue (ex: https://intlayer.org/aboutintlayer.org).
    2. window.location.hostname dans les environnements de navigation.
    3. Si aucun n'est disponible (SSR sans option explicite), une URL relative est retournée pour les locales du même domaine et aucune URL absolue n'est produite - c'est le repli sécurisé.
    ts
    // Navigateur - window.location.hostname === 'intlayer.org'getLocalizedUrl("/about", "zh");// → "https://intlayer.zh/about"  (détecté automatiquement à partir de window)// À partir d'une URL absolue - domaine détecté automatiquementgetLocalizedUrl("https://intlayer.org/about", "zh");// → "https://intlayer.zh/about"

    getMultilingualUrls avec domaines

    getMultilingualUrls appelle getLocalizedUrl pour chaque locale, il produit donc un mélange d'URLs relatives et absolues selon le domaine de l'appelant :

    ts
    // currentDomain: 'intlayer.org'getMultilingualUrls("/about", { currentDomain: "intlayer.org" });// {//   en: "/about",//   fr: "/fr/about",//   es: "/es/about",//   zh: "https://intlayer.zh/about",// }

    Ces URLs absolues sont prêtes à être utilisées dans les balises <link rel="alternate" hreflang="..."> pour le SEO.

    Comportement du Proxy

    Next.js

    Le middleware intlayerProxy gère automatiquement le routage par domaine. Ajoutez-le à votre middleware.ts :

    middleware.ts
    export { intlayerProxy as default } from "next-intlayer/proxy";export const config = {  matcher: "/((?!api|static|assets|robots|sitemap|.*\\..*|_next).*)",};

    Redirection - la requête arrive sur le mauvais domaine pour un préfixe de locale donné :

    plaintext
    GET intlayer.org/zh/about→ 301 https://intlayer.zh/about

    Réécriture - la requête arrive sur le domaine exclusif de la locale sans préfixe :

    plaintext
    GET intlayer.zh/about→ réécriture vers /zh/about  (routage interne Next.js uniquement, l'URL reste propre)

    Vite

    Le plugin Vite intlayerProxy applique la même logique pendant le développement :

    vite.config.ts
    import { defineConfig } from "vite";import { intlayerProxy } from "vite-intlayer";export default defineConfig({  plugins: [intlayerProxy()],});
    Note : en développement local, vous êtes généralement sur localhost, donc les redirections inter-domaines pointeront vers les domaines en direct plutôt que vers un autre port local. Utilisez une substitution dans le fichier hosts (ex: 127.0.0.1 intlayer.zh) ou un proxy inverse si vous avez besoin de tester le routage multi-domaines localement.

    Sélecteur de locale

    Le hook useLocale de next-intlayer gère automatiquement la navigation tenant compte du domaine. Lorsqu'un utilisateur passe à une locale sur un domaine différent, le hook effectue une navigation de page complète (window.location.href) au lieu d'un push du routeur côté client, car le routeur Next.js ne peut pas traverser les origines.

    components/LocaleSwitcher.tsx
    "use client";import { useLocale } from "next-intlayer";export const LocaleSwitcher = () => {  const { availableLocales, locale, setLocale } = useLocale();  return (    <ul>      {availableLocales.map((localeEl) => (        <li key={localeEl}>          <button            onClick={() => setLocale(localeEl)}            aria-current={localeEl === locale ? "true" : undefined}          >            {l.toUpperCase()}          </button>        </li>      ))}    </ul>  );};

    Aucune configuration supplémentaire n'est requise - useLocale détecte window.location.hostname en interne et décide entre router.replace (même domaine) et window.location.href (domaine différent).

    SEO : Liens alternatifs hreflang

    Le routage par domaine est couramment utilisé avec hreflang pour indiquer aux moteurs de recherche quelle URL indexer pour chaque langue. Utilisez getMultilingualUrls pour générer l'ensemble complet des URLs alternatives :

    app/[locale]/layout.tsx
    import { getMultilingualUrls } from "intlayer";import type { Metadata } from "next";export const generateMetadata = (): Metadata => {  const alternates = getMultilingualUrls("/", {    currentDomain: process.env.NEXT_PUBLIC_DOMAIN, // ex: "intlayer.org"  });  return {    alternates: {      languages: alternates,    },  };};

    Cela produit :

    html
    <link rel="alternate" hreflang="en" href="https://intlayer.org/" /><link rel="alternate" hreflang="fr" href="https://intlayer.org/fr/" /><link rel="alternate" hreflang="es" href="https://intlayer.org/es/" /><link rel="alternate" hreflang="zh" href="https://intlayer.zh/" />

    Utilitaires de base

    Utilitaire Description
    getLocalizedUrl(url, locale, { currentDomain }) Retourne une URL relative ou absolue selon que la locale cible est sur le domaine actuel ou non.
    getMultilingualUrls(url, { currentDomain }) Retourne une carte des URLs localisées par locale, mélangeant relatives et absolues selon les besoins.
    getPrefix(locale, { domains }) Retourne un préfixe vide pour les locales à domaine exclusif, sinon le préfixe normal.