Gestion des codes de langue non pris en charge
Problème
Une application utilise le chemin d'URL (par exemple, /en/, /fr/) pour déterminer la langue, mais les utilisateurs peuvent saisir manuellement n'importe quelle valeur, comme /xx/about. Lorsque cette valeur ne correspond à aucune langue prise en charge, l'application peut planter, afficher une erreur générique ou présenter du contenu non traduit, sans guider l'utilisateur vers une expérience valide.
Solution
Utilisez un middleware pour intercepter toutes les requêtes entrantes. Ce middleware validera le code de langue de l'URL par rapport à une liste définitive des langues prises en charge. Si le code n'est pas pris en charge, la requête sera réécrite vers une page « Introuvable » avant d'atteindre la logique de l'application.
Étapes
1. Définissez vos langues prises en charge
Créez un fichier de configuration central pour stocker votre liste de codes de langue (locales) valides. Cela rend la liste réutilisable pour votre middleware et d'autres parties de votre application.
// i18n.config.ts
export const locales = ['en', 'es', 'fr'];
2. Créez le fichier middleware
Créez un nouveau fichier nommé middleware.ts à la racine de votre projet (ou dans votre répertoire src/). Next.js détectera automatiquement ce fichier et l'exécutera sur les requêtes.
// middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
import { locales } from './i18n.config';
export function middleware(request: NextRequest) {
// Logic will go here in the next step
}
3. Ajoutez la logique de validation
À l'intérieur de la fonction middleware, récupérez le pathname de la requête. Nous devons vérifier le premier segment du chemin (par exemple, en dans /en/about) et voir s'il s'agit d'une langue valide et prise en charge.
// middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
import { locales } from './i18n.config';
export function middleware(request: NextRequest) {
const { pathname } = request.nextUrl;
// 1. Handle the root path separately
// (This will be handled by the next recipe: "Detecting a user's
// preferred language"). For now, we just let it pass.
if (pathname === '/') {
return NextResponse.next();
}
// 2. Extract the language code from the path
const langCode = pathname.split('/')[1];
// 3. Check if the language code is in our list
if (locales.includes(langCode)) {
// Language is valid, continue to the requested page
return NextResponse.next();
}
// 4. If the language is not valid, rewrite to a 404 page
// This keeps the invalid URL in the browser bar
const url = request.nextUrl.clone();
url.pathname = `/404`; // Assumes you have an app/404.tsx file
return NextResponse.rewrite(url);
}
Cette logique vérifie chaque requête. Si l'URL est /fr/about, langCode est fr, il est trouvé dans locales, et la requête continue. Si l'URL est /xx/about, langCode est xx, il n'est pas trouvé, et l'utilisateur voit la page 404 sans que l'application n'essaie de traiter la requête invalide.
4. Configurer le matcher du middleware
Pour rendre votre middleware plus efficace, vous devez lui indiquer sur quels chemins il doit s'exécuter. Nous voulons qu'il s'exécute sur les requêtes de pages mais qu'il ignore les fichiers statiques et les routes API.
Ajoutez un objet config en bas de votre fichier middleware.ts.
// middleware.ts
// ... (the middleware function from above)
export const config = {
matcher: [
// Skip all paths that start with:
// - api (API routes)
// - _next/static (static files)
// - _next/image (image optimization files)
// - favicon.ico (favicon file)
'/((?!api|_next/static|_next/image|favicon.ico).*)',
],
};
Cette expression régulière indique au middleware de s'exécuter sur tous les chemins sauf ceux qui sont généralement destinés aux ressources statiques ou aux appels API. Cela évite une validation inutile sur chaque requête d'image, de police ou de données.