Pourquoi Internationalisation (i18n) avec Next.js ?
Dans un monde globalisé où les utilisateurs sont répartis sur de nombreux pays et régions, l'internationalisation (i18n) est une pratique cruciale pour les développeurs web. L'i18n permet d'offrir aux utilisateurs des interfaces utilisateur personnalisées en fonction de leur langue préférée, ce qui améliore la compréhension du contenu et augmente l'engagement.
Un cas d'utilisation concret est une application multilingue comme une plateforme de tourisme où les visiteurs peuvent choisir de consulter le site en français, en anglais ou en espagnol pour obtenir des informations locales et pertinentes.
Prerequis
- Connaissance de base de React
- Familiarité avec Next.js
- Compréhension des concepts de l'application universelle (Universal Application)
- Installation de Node.js (v14.x ou supérieur)
- Installation de npm (Node Package Manager)
Concepts fondamentaux
1. Configurations locales et régionales
La première étape consiste à définir les configurations locales et régionales pour chaque langue supportée.
// next.config.js
module.exports = {
i18n: {
locales: ['en', 'fr', 'es'], // Langues supportées
defaultLocale: 'en', // Langue par défaut
},
};
2. Utilisation des composants de traduction
Next.js utilise next-intl pour la gestion des traductions.
npm install next-intl --save
Créer un fichier de traduction dans le répertoire public/locales.
// public/locales/en/common.json
{
"welcome": "Welcome to our site",
"menu": {
"home": "Home"
}
}
3. Composant de traduction
Créer un composant React pour gérer la traduction.
// components/Translate.js
import { useTranslation } from 'next-intl';
const Translate = ({ id, values }) => {
const { t } = useTranslation();
return t(id, values);
};
export default Translate;
4. Utilisation du composant dans une page
// pages/index.js
import Translate from '../components/Translate';
const HomePage = () => (
<div>
<h1><Translate id="welcome" /></h1>
<nav>
<ul>
<li><Translate id="menu.home" /></li>
</ul>
</nav>
</div>
);
export default HomePage;
Mise en pratique : projet fil rouge
Nous allons construire un simple site web multilingue avec une page d'accueil et une page de contact.
Étape 1 : Création du projet Next.js
npx create-next-app@latest i18n-nextjs-tutorial
cd i18n-nextjs-tutorial
Étape 2 : Configuration de l'i18n
Modifier next.config.js comme suit :
// next.config.js
module.exports = {
i18n: {
locales: ['en', 'fr', 'es'],
defaultLocale: 'en',
},
};
Étape 3 : Création des fichiers de traduction
Créer les fichiers de traduction pour chaque langue dans public/locales.
// public/locales/en/common.json
{
"welcome": "Welcome to our site",
"menu": {
"home": "Home",
"about": "About Us"
},
"contact": {
"title": "Contact Us",
"form": {
"name": "Your Name",
"email": "Your Email",
"message": "Message",
"submit": "Send"
}
}
}
Étape 4 : Composant de traduction
Créer le composant Translate.js.
// components/Translate.js
import { useTranslation } from 'next-intl';
const Translate = ({ id, values }) => {
const { t } = useTranslation();
return t(id, values);
};
export default Translate;
Étape 5 : Page d'accueil
Créer la page d'accueil pages/index.js.
// pages/index.js
import Translate from '../components/Translate';
const HomePage = () => (
<div>
<h1><Translate id="welcome" /></h1>
<nav>
<ul>
<li><Translate id="menu.home" /></li>
<li><Translate id="menu.about" /></li>
</ul>
</nav>
</div>
);
export default HomePage;
Étape 6 : Page de contact
Créer la page de contact pages/contact.js.
// pages/contact.js
import Translate from '../components/Translate';
const ContactPage = () => (
<div>
<h1><Translate id="contact.title" /></h1>
<form>
<label htmlFor="name"><Translate id="contact.form.name" /></label>
<input type="text" id="name" name="name" />
<label htmlFor="email"><Translate id="contact.form.email" /></label>
<input type="email" id="email" name="email" />
<label htmlFor="message"><Translate id="contact.form.message" /></label>
<textarea id="message" name="message"></textarea>
<button type="submit"><Translate id="contact.form.submit" /></button>
</form>
</div>
);
export default ContactPage;
Étape 7 : Ajout de langues
Pour ajouter des langues, vous pouvez simplement modifier la configuration next.config.js et créer les fichiers de traduction correspondants.
## next.config.js
module.exports = {
i18n: {
locales: ['en', 'fr', 'es'],
defaultLocale: 'en',
},
};
Erreurs frequentes et debugging
1. Erreur : Traduction non trouvée
## ❌ Mauvais
const { t } = useTranslation();
t('non_existent_key');
// ✅ Correct
const { t } = useTranslation();
t('welcome', { default: 'Welcome to our site' });
2. Erreur : Langue non définie
## ❌ Mauvais
next.config.js
i18n: {
locales: ['fr'],
}
// ✅ Correct
next.config.js
i18n: {
locales: ['fr'],
defaultLocale: 'fr',
},
3. Erreur : Contexte de traduction manquant
## ❌ Mauvais
import Translate from '../components/Translate';
const HomePage = () => (
<div>
<h1><Translate id="welcome" /></h1> // Sans useTranslation()
</div>
);
// ✅ Correct
import { useTranslation } from 'next-intl';
import Translate from '../components/Translate';
const HomePage = () => {
const { t } = useTranslation();
return (
<div>
<h1><Translate id="welcome" /></h1>
</div>
);
};
Pour aller plus loin
1. Utilisation de l'API next-intl-server pour les API
npm install next-intl-server --save
Créer un fichier de traduction pour les API.
// public/locales/en/api.json
{
"greeting": "Hello"
}
Utiliser la fonction useIntlServer dans une API Next.js.
// pages/api/greet.js
import { useIntlServer } from 'next-intl-server';
export default function handler(req, res) {
const intl = useIntlServer({ locale: req.headers['accept-language'] });
const greeting = intl.t('api.greeting');
res.status(200).json({ message: greeting });
}
2. Utilisation de contexte global
Créer un contexte global pour partager la langue entre les composants.
// components/LanguageContext.js
import { createContext, useContext } from 'react';
const LanguageContext = createContext();
export const useLanguage = () => useContext(LanguageContext);
export const LanguageProvider = ({ children }) => {
const [locale, setLocale] = useState('en');
return (
<LanguageContext.Provider value=locale, setLocale>
{children}
</LanguageContext.Provider>
);
};
Utiliser le contexte dans les composants.
// pages/_app.js
import '../styles/globals.css';
import LanguageProvider from '../components/LanguageProvider';
export default function MyApp({ Component, pageProps }) {
return (
<LanguageProvider>
<Component {...pageProps} />
</LanguageProvider>
);
}
3. Utilisation de middleware pour gérer la langue
Créer un middleware pour définir la langue en fonction des en-têtes.
// lib/middleware.js
import { NextResponse } from 'next/server';
import i18n from '../next.config.js';
export function middleware(request) {
const defaultLocale = i18n.defaultLocale;
let locale = request.headers.get('accept-language') || defaultLocale;
// Vérifier si la langue est supportée
if (!i18n.locales.includes(locale)) {
locale = defaultLocale;
}
return NextResponse.rewrite(
new URL(`/${locale}/${request.nextUrl.pathname}`, request.url),
request
);
}
export const config = {
matcher: [
'/((?!api|_next/static|favicon.ico).*)',
],
};
Ajouter le middleware à middleware.js dans le répertoire lib.
Défi pratique
Créer une application simple avec des pages d'accueil, de contact et de produits. Assurez-vous que chaque page est disponible en trois langues différentes (français, anglais et espagnol). Utilisez les composants de traduction pour afficher le contenu dynamiquement en fonction de la langue sélectionnée.
Bon codage !