SPB Git
2.0 KB · 25 lines typescript
1import { NextResponse, type NextRequest } from "next/server";2/**3 * Locale routing. Canonical public URLs are unprefixed (English); French lives under `/fr/...`.4 * Internally every public page sits under an `[locale]` segment so that cached renders never leak across languages:5 *   /papers/wp38     → rewrite → /en/papers/wp38   (x-locale: en)6 *   /fr/papers/wp38  → as is   → /fr/papers/wp38   (x-locale: fr)7 *   /en/...          → 308 redirect to the canonical unprefixed URL8 * Also exposes the pathname to server components (auth guard) and keeps a `lang` cookie for the UI.9 */10const PASS = /^\/(api(?!\/docs$)|admin|login|_next|feed\.xml|sitemap\.xml|robots\.txt|favicon\.ico|brand|fonts|icon|apple-icon|opengraph-image)(\/|$)/;11export function proxy(req: NextRequest) {12  const { pathname, search } = req.nextUrl;13  const h = new Headers(req.headers); h.set("x-pathname", pathname);14  // A rewritten request re-enters the proxy with the internal `/en/...` path: let it through untouched.15  if (req.headers.get("x-wp-rewritten") === "1" || (pathname.startsWith("/en/") && req.headers.get("x-locale") === "en")) return NextResponse.next({ request: { headers: h } });16  if (PASS.test(pathname)) { h.set("x-locale", pathname.startsWith("/fr") ? "fr" : "en"); return NextResponse.next({ request: { headers: h } }); }17  if (pathname === "/en" || pathname.startsWith("/en/")) return NextResponse.redirect(new URL((pathname.slice(3) || "/") + search, req.url), 308);18  const fr = pathname === "/fr" || pathname.startsWith("/fr/");19  h.set("x-locale", fr ? "fr" : "en"); h.set("x-wp-rewritten", "1");20  const res = fr ? NextResponse.next({ request: { headers: h } }) : NextResponse.rewrite(new URL(`/en${pathname === "/" ? "" : pathname}${search}`, req.url), { request: { headers: h } });21  const want = fr ? "fr" : "en"; if (req.cookies.get("lang")?.value !== want) res.cookies.set("lang", want, { path: "/", maxAge: 31536000, sameSite: "lax" });22  return res;23}24export const config = { matcher: ["/((?!_next/static|_next/image|favicon.ico).*)"] };25
Files · 2db8b968446e61b102004934d20027a0ac28f0f5
Menu

Theme