Articlepar DevBlog

Migrer de middleware.ts vers proxy.ts dans Next.js 16

middleware.ts est déprécié dans Next.js 16. Voici comment passer à proxy.ts, et un cas d'usage concret : renvoyer un vrai 404 pour les slugs inconnus.

  • #nextjs
  • #proxy
  • #migration

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

typescript
// 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+"] };
typescript
// 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 :

typescript
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, fonction proxy, 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.