You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

62 lines
2.3 KiB

import { type NextRequest, NextResponse } from "next/server";
import { defaultLocale, isLocale } from "@/translations/config";
function getPreferredLocale(request: NextRequest) {
const cookieLocale =
request.cookies.get("HABIB_LANGUAGE")?.value ??
request.cookies.get("habib_language")?.value;
if (cookieLocale) {
const normalizedCookie = cookieLocale.trim().toLowerCase();
if (isLocale(normalizedCookie)) return normalizedCookie;
}
// Walk the full Accept-Language list (not only the first entry): some
// devices send `fa-IR, fa;q=0.9, en;q=0.8` where the region subtag belongs
// to the first entry but a bare supported language follows. Normalize
// region/case (`fa-IR` → `fa`, `zh-Hans-CN` → `zh`) and skip wildcards.
const acceptLanguage = request.headers.get("accept-language") ?? "";
for (const part of acceptLanguage.split(",")) {
const tag = part.split(";")[0]?.trim().toLowerCase();
if (!tag || tag === "*") continue;
const language = tag.split("-")[0];
if (isLocale(language)) return language;
}
return defaultLocale;
}
export function proxy(request: NextRequest) {
const { pathname } = request.nextUrl;
const pathnameLocale = pathname.split("/")[1];
const pathnameHasLocale = isLocale(pathnameLocale);
const cookieLocale =
request.cookies.get("HABIB_LANGUAGE")?.value ??
request.cookies.get("habib_language")?.value;
const authoritativeLocale = isLocale(cookieLocale?.toLowerCase())
? cookieLocale.toLowerCase()
: null;
if (pathnameHasLocale) {
if (authoritativeLocale && authoritativeLocale !== pathnameLocale) {
const url = request.nextUrl.clone();
const segments = pathname.split("/");
segments[1] = authoritativeLocale;
url.pathname = segments.join("/");
return NextResponse.redirect(url);
}
const requestHeaders = new Headers(request.headers);
requestHeaders.set("x-habib-locale", pathnameLocale);
return NextResponse.next({ request: { headers: requestHeaders } });
}
const locale = getPreferredLocale(request);
const url = request.nextUrl.clone();
url.pathname = `/${locale}${pathname === "/" ? "" : pathname}`;
return NextResponse.redirect(url);
}
export const config = {
matcher: ["/((?!api|_next|favicon.ico|healthz|assets|fonts).*)"],
};