Par coderoe · 5 min de lecture
Avec plus de 4,6 milliards d'internautes dans le monde, proposer votre contenu dans plusieurs langues peut multiplier votre audience par 3. Next International est la solution la plus simple pour transformer votre site Next.js en plateforme multilingue, sans complexité technique excessive.
Ce que vous allez accomplir :
Créons un nouveau projet Next.js avec TypeScript (recommandé pour une meilleure expérience de développement).
pnpm create next-app@latest my-app --yes
cd my-app
Astuce : Utilisez
pnpm
pour des installations plus rapides, ou remplacez parnpm
ouyarn
selon vos préférences.
Ajoutons Next International à notre projet. Cette librairie est légère (moins de 50KB) et optimisée pour Next.js 13+.
pnpm install next-international
Pourquoi Next International ?
- Plus simple que react-i18next
- Optimisé pour App Router de Next.js
- Support TypeScript natif
- Détection automatique de la langue
Créons la structure de fichiers pour gérer nos traductions. Nous allons organiser tout dans un dossier src/locale/
pour une meilleure lisibilité.
Créer le dossier : src/locale/
src/
├── locale/
│ ├── client.ts # Configuration côté client
│ ├── server.ts # Configuration côté serveur
│ ├── en/
│ │ └── index.ts # Traductions anglaises
│ └── fr/
│ └── index.ts # Traductions françaises
Créer le fichier : src/locale/client.ts
Explication : Ce fichier configure Next International pour le côté client (composants interactifs, hooks, etc.)
// locales/client.ts
"use client"
import { createI18nClient } from 'next-international/client'
export const {
useI18n,
useScopedI18n,
I18nProviderClient,
useCurrentLocale,
useChangeLocale,
} = createI18nClient({
en: () => import('./en'),
fr: () => import('./fr')
})
export type Locale = 'en' | 'fr'
Créer le fichier : src/locale/server.ts
Explication : Ce fichier configure Next International pour le côté serveur (Server Components, génération statique, etc.)
// locales/server.ts
import { createI18nServer } from 'next-international/server'
export const { getI18n, getScopedI18n, getStaticParams } = createI18nServer({
en: () => import('./en'),
fr: () => import('./fr')
})
Créer les dossiers et fichiers : src/locale/en/index.ts
et src/locale/fr/index.ts
Explication : Ces fichiers contiennent vos traductions. Chaque clé correspond à un texte à traduire. Vous pouvez organiser vos traductions par sections (ex:
'header.title'
,'footer.copyright'
).
// locales/en.ts
export default {
'hello': 'Hello',
'hello.world': 'Hello world!',
'welcome': 'Hello {name}!'
} as const
et
// locales/fr.ts
export default {
'hello': 'Bonjour',
'hello.world': 'Bonjour tout le monde!',
'welcome': 'Bonjour {name}!'
} as const
Modifier le fichier : app/layout.tsx
Créer le dossier src/[locale]
pour déplacer tous les fichiers dans celui-ci
src/
├── app/
│ ├── favicon.ico
│ ├── [locale]
│ └── globals.css
│ └── layout.tsx
│ └── page.tsx
Explication : Le Provider enveloppe toute votre application pour rendre les traductions disponibles partout. Il détecte automatiquement la langue de l'utilisateur.
import type { Metadata } from "next";
import { Geist, Geist_Mono } from "next/font/google";
import "./globals.css";
import { I18nProviderClient } from "@/locale/client";
const geistSans = Geist({
variable: "--font-geist-sans",
subsets: ["latin"],
});
const geistMono = Geist_Mono({
variable: "--font-geist-mono",
subsets: ["latin"],
});
export const metadata: Metadata = {
title: "Create Next App",
description: "Generated by create next app",
};
export default async function RootLayout({
children,
params,
}: Readonly<{
children: React.ReactNode;
params: Promise<{ locale: string }>;
}>) {
const { locale } = await params
return (
<html lang={locale}>
<body
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
>
<I18nProviderClient locale={locale}>
{children}
</I18nProviderClient>
</body>
</html>
);
}
Créer le fichier : src/middleware.ts
Explication : Le middleware intercepte les requêtes pour détecter la langue préférée de l'utilisateur et rediriger vers la bonne version linguistique de votre site.
// middleware.ts
import { createI18nMiddleware } from 'next-international/middleware'
import { NextRequest } from 'next/server'
const I18nMiddleware = createI18nMiddleware({
locales: ['en', 'fr'],
defaultLocale: 'en'
})
export function middleware(request: NextRequest) {
return I18nMiddleware(request)
}
export const config = {
matcher: ['/((?!api|static|.*\\..*|_next|favicon.ico|robots.txt).*)']
}
Maintenant que tout est configuré, utilisons les traductions dans nos composants !
Modifier le fichier : app/page.tsx
Explication : Le hook
useI18n()
vous donne accès à la fonction de traductiont()
. Passez simplement la clé de traduction pour obtenir le texte dans la langue active.
"use client";
import { useI18n } from "@/locale/client";
export default function Home() {
const t = useI18n();
return (
<div className="flex flex-col items-center justify-center h-screen">
<p>{t("hello")}</p>
</div>
);
}
Vous pouvez inclure des variables dans vos traductions :
// Dans vos fichiers de traduction
'welcome': 'Bonjour {name}!', // fr
'welcome': 'Hello {name}!', // en
// Dans votre composant
<p>{t('welcome', { name: 'Marie' })}</p>
// Affiche : "Bonjour Marie!" ou "Hello Marie!"
Pour les Server Components, utilisez getI18n()
:
import { getI18n } from '@/locale/server';
export default async function ServerComponent() {
const t = await getI18n();
return <h1>{t('hello')}</h1>;
}
import { useCurrentLocale, useChangeLocale, Locale } from '@/locale/client';
export default function LanguageSwitcher() {
const locale = useCurrentLocale();
const changeLocale = useChangeLocale();
return (
<select value={locale} onChange={(e) => changeLocale(e.target.value as Locale)}>
<option value="fr">Français</option>
<option value="en">English</option>
</select>
);
}
Testez votre configuration :
pnpm dev
http://localhost:3000
http://localhost:3000/fr
ou http://localhost:3000/en
Votre site Next.js est maintenant multilingue !
Prochaines étapes :
Ressources utiles :