Cómo validar parámetros de locale en URLs en Next.js (Pages Router) v16
Gestiona códigos de locale no soportados de forma elegante
Problema
Cuando los códigos de locale forman parte de la estructura de URL, se transforman en entrada de usuario que debe ser validada. Un visitante puede escribir /xx/about o /gibberish/contact tan fácilmente como un locale válido como /en/about. Sin validación, la aplicación puede fallar, mostrar contenido roto o mensajes de error confusos. Los usuarios que encuentran URLs de locale inválidas necesitan un camino claro a seguir, ya sea mediante redirección a un locale válido o una respuesta "No encontrado" apropiada que les ayude a entender qué salió mal.
Solución
Valida los parámetros de locale entrantes contra una lista de locales soportados antes de que la solicitud llegue a los componentes de página. Usa middleware de Next.js para interceptar solicitudes, verificar si el locale en la URL coincide con un valor soportado y responder apropiadamente. Para locales inválidos, redirige al usuario al locale predeterminado o reescribe la solicitud para mostrar una página 404. Esto asegura que solo códigos de locale válidos procedan a renderizar contenido, mientras que los códigos inválidos se gestionan de forma elegante sin romper la experiencia del usuario.
Pasos
1. Define los locales soportados en la configuración de Next.js
Configura los ajustes de i18n en next.config.js para declarar qué locales soporta tu aplicación y cuál locale sirve como predeterminado.
module.exports = {
i18n: {
locales: ["en", "fr", "de"],
defaultLocale: "en",
localeDetection: false,
},
};
Establecer localeDetection en false previene redirecciones automáticas basadas en preferencias del navegador, dándote control total sobre el manejo de locales.
2. Crea middleware para validar parámetros de locale
Crea un archivo middleware.ts en la raíz de tu proyecto o dentro de la carpeta src si estás usando una.
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|.*\\..*).*)"],
};
El middleware extrae la configuración regional de la ruta de la URL, la compara con el array de configuraciones regionales admitidas y redirige las configuraciones regionales no válidas a la configuración regional predeterminada mientras conserva el resto de la ruta.
3. Gestionar configuraciones regionales no válidas con una respuesta 404
Si prefieres mostrar una página 404 en lugar de redirigir, reescribe la solicitud a la página 404 personalizada.
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|.*\\..*).*)"],
};
Crea una página 404 personalizada en pages/404.js que se genera estáticamente en tiempo de compilación.
4. Crear una página 404 personalizada
export default function Custom404() {
return (
<div>
<h1>404 - Page Not Found</h1>
<p>The page you are looking for does not exist.</p>
</div>
);
}
Esta página se muestra cuando el middleware reescribe solicitudes de configuración regional no válidas, proporcionando a los usuarios un mensaje claro de que la URL solicitada no está disponible.