Ce qui change
Dans Next.js 16, middleware.ts est déprécié et remplacé par proxy.ts. Le fichier garde le même rôle : s'exécuter avant qu'une requête n'atteigne une route, pour réécrire, rediriger ou répondre directement.
Deux différences à retenir :
- la fonction exportée s'appelle
proxy; - le runtime est Node.js.
Avant / après
// middleware.ts (déprécié)
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";
export function middleware(request: NextRequest) {
return NextResponse.next();
}
export const config = { matcher: ["/articles/:path+"] };// proxy.ts
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";
export function proxy(request: NextRequest) {
return NextResponse.next();
}
export const config = { matcher: ["/articles/:path+"] };La migration est essentiellement un renommage du fichier et de la fonction. Pensez à relire la documentation de votre version dans node_modules/next/dist/docs/ : les API évoluent.
Un cas d'usage : le vrai 404
Les routes de contenu sont partiellement prérendues. Sans filtre, un slug inconnu renvoie la page « introuvable » avec un statut 200 (soft 404). Le proxy règle le problème :
export async function proxy(request: NextRequest) {
const [, section, slug] = request.nextUrl.pathname.split("/");
if (!isValidSlug(slug) || !contentExists(section, slug)) {
return NextResponse.rewrite(new URL("/404", request.url), { status: 404 });
}
return NextResponse.next();
}Le rewrite affiche la page 404 stylée avec le bon statut.
Garder le proxy léger
Le proxy s'exécute à chaque requête correspondant au matcher. Il faut donc :
- n'importer que le strict nécessaire (pas de Markdown ni de cache) ;
- éviter les traitements coûteux ;
- cibler précisément le
matcher.
Dans ce blog, la résolution de chemin confinée vit dans un module dédié, sans dépendance lourde, précisément pour cette raison.
Tester le proxy
Le proxy se teste en test unitaire en lui passant une requête fabriquée, et en vérifiant le statut :
- slug valide et existant → la requête passe ;
- slug inconnu, majuscules,
..%2f, octet nul → 404.
À retenir
middleware.ts→proxy.ts, fonctionproxy, runtime Node.js.- Idéal pour les redirections, réécritures et vrais 404.
- Gardez-le rapide : il est sur le chemin de chaque requête.