import { NextResponse } from "next/server"; import type { NextRequest } from "next/server"; import { i18n } from "./i18n-config"; function getLocale(request: NextRequest): string { const acceptLanguage = request.headers.get("accept-language"); if (!acceptLanguage) return i18n.defaultLocale; // Simple and ultra-robust parsing for accept-language header const preferredLocales = acceptLanguage .split(",") .map((lang) => { const [locale, q] = lang.split(";q="); return { locale: locale.trim().split("-")[0].toLowerCase(), // e.g. "tr", "en" priority: q ? parseFloat(q) : 1.0, }; }) .sort((a, b) => b.priority - a.priority); for (const pref of preferredLocales) { if (i18n.locales.includes(pref.locale as any)) { return pref.locale; } } return i18n.defaultLocale; } export function proxy(request: NextRequest) { const pathname = request.nextUrl.pathname; // Skip static assets, internal paths, and favicon if ( pathname.startsWith("/_next") || pathname.startsWith("/api") || pathname.startsWith("/favicon.ico") || pathname.match(/\.(png|jpg|jpeg|gif|svg|webp|ico|css|js|woff|woff2|ttf|otf|json)$/) ) { return; } // Check if pathname already contains a supported locale prefix const pathnameIsMissingLocale = i18n.locales.every( (locale) => !pathname.startsWith(`/${locale}/`) && pathname !== `/${locale}` ); if (pathnameIsMissingLocale) { const locale = getLocale(request); // Redirect /xxx to /locale/xxx return NextResponse.redirect( new URL( `/${locale}${pathname.startsWith("/") ? "" : "/"}${pathname}`, request.url ) ); } } export const config = { // Matcher ignoring static items and api routes matcher: ["/((?!api|_next/static|_next/image|favicon.ico).*)"], };