Comment valider les paramètres de locale dans les URLs avec Next.js (Pages Router) v16

Gérer les codes de locale non pris en charge avec élégance

Problème

Lorsque les codes de langue deviennent partie intégrante de la structure d'URL, ils se transforment en données saisies par l'utilisateur qui doivent être validées. Un visiteur peut aussi facilement taper /xx/about ou /gibberish/contact qu'une langue valide comme /en/about. Sans validation, l'application peut planter, afficher du contenu défectueux ou des messages d'erreur déroutants. Les utilisateurs qui rencontrent des URL avec des langues invalides ont besoin d'une voie claire à suivre—soit par une redirection vers une langue valide, soit par une réponse "Non trouvé" appropriée qui les aide à comprendre ce qui n'a pas fonctionné.

Solution

Validez les paramètres de langue entrants par rapport à une liste de langues prises en charge avant que la requête n'atteigne les composants de la page. Utilisez le middleware de Next.js pour intercepter les requêtes, vérifier si la langue dans l'URL correspond à une valeur prise en charge et répondre de manière appropriée. Pour les langues invalides, redirigez l'utilisateur vers la langue par défaut ou réécrivez la requête pour afficher une page 404. Cela garantit que seuls les codes de langue valides procèdent au rendu du contenu, tandis que les codes invalides sont traités avec élégance sans nuire à l'expérience utilisateur.

Étapes

1. Définir les langues prises en charge dans la configuration Next.js

Configurez les paramètres i18n dans next.config.js pour déclarer quelles langues votre application prend en charge et quelle langue sert de langue par défaut.

module.exports = {
  i18n: {
    locales: ["en", "fr", "de"],
    defaultLocale: "en",
    localeDetection: false,
  },
};

Définir localeDetection à false empêche les redirections automatiques basées sur les préférences du navigateur, vous donnant un contrôle total sur la gestion des langues.

2. Créer un middleware pour valider les paramètres de langue

Créez un fichier middleware.ts à la racine de votre projet ou dans le dossier src si vous en utilisez un.

import { NextRequest, NextResponse } from "next/server";

const SUPPORTED_LOCALES = ["en", "fr", "de"];
const DEFAULT_LOCALE = "en";

export function middleware(request: NextRequest) {
  const { pathname } = request.nextUrl;

  const pathnameHasLocale = SUPPORTED_LOCALES.some(
    (locale) => pathname.startsWith(`/${locale}/`) || pathname === `/${locale}`,
  );

  if (!pathnameHasLocale) {
    return;
  }

  const localeInPath = pathname.split("/")[1];

  if (!SUPPORTED_LOCALES.includes(localeInPath)) {
    const url = request.nextUrl.clone();
    url.pathname = pathname.replace(`/${localeInPath}`, `/${DEFAULT_LOCALE}`);
    return NextResponse.redirect(url);
  }
}

export const config = {
  matcher: ["/((?!_next|api|favicon.ico|.*\\..*).*)"],
};

Le middleware extrait la langue de l'URL, la vérifie par rapport au tableau des langues prises en charge, et redirige les langues invalides vers la langue par défaut tout en préservant le reste du chemin.

3. Gérer les locales invalides avec une réponse 404

Si vous préférez afficher une page 404 au lieu de rediriger, réécrivez la requête vers la page 404 personnalisée.

import { NextRequest, NextResponse } from "next/server";

const SUPPORTED_LOCALES = ["en", "fr", "de"];

export function middleware(request: NextRequest) {
  const { pathname } = request.nextUrl;

  const pathnameHasLocale = SUPPORTED_LOCALES.some(
    (locale) => pathname.startsWith(`/${locale}/`) || pathname === `/${locale}`,
  );

  if (!pathnameHasLocale) {
    return;
  }

  const localeInPath = pathname.split("/")[1];

  if (!SUPPORTED_LOCALES.includes(localeInPath)) {
    const url = request.nextUrl.clone();
    url.pathname = "/404";
    return NextResponse.rewrite(url);
  }
}

export const config = {
  matcher: ["/((?!_next|api|favicon.ico|.*\\..*).*)"],
};

Créez une page 404 personnalisée à pages/404.js qui est générée statiquement lors de la compilation.

4. Créer une page 404 personnalisée

export default function Custom404() {
  return (
    <div>
      <h1>404 - Page non trouvée</h1>
      <p>La page que vous recherchez n'existe pas.</p>
    </div>
  );
}

Cette page s'affiche lorsque le middleware réécrit les requêtes avec des locales invalides, fournissant aux utilisateurs un message clair indiquant que l'URL demandée n'est pas disponible.