import { NextResponse } from 'next/server'; import type { NextRequest } from 'next/server'; import { SUPPORTED_LOCALES, DEFAULT_LOCALE } from './lib/locales'; // Paths that should not be localized const PUBLIC_FILE = /\.(.*)$/; const SKIP_PATHS = ['/_next', '/api', '/favicon.ico', '/robots.txt', '/sitemap.xml', '/sitemap']; export function proxy(request: NextRequest) { const { pathname } = request.nextUrl; // Skip Next.js internals, APIs, and public files if ( SKIP_PATHS.some((p) => pathname.startsWith(p)) || PUBLIC_FILE.test(pathname) ) { return NextResponse.next(); } // Check if the pathname already has a locale const matchedLocale = SUPPORTED_LOCALES.find( (locale) => pathname.startsWith(`/${locale}/`) || pathname === `/${locale}` ); if (matchedLocale) { const requestHeaders = new Headers(request.headers); requestHeaders.set('x-homaroma-locale', matchedLocale); return NextResponse.next({ request: { headers: requestHeaders, }, }); } // Determine the preferred locale // 1. Check cookie const cookieLocale = request.cookies.get('app_lang')?.value; let targetLocale = DEFAULT_LOCALE; if (cookieLocale && (SUPPORTED_LOCALES as readonly string[]).includes(cookieLocale)) { targetLocale = cookieLocale as typeof SUPPORTED_LOCALES[number]; } else { // 2. Check Accept-Language header const acceptLang = request.headers.get('accept-language'); if (acceptLang) { const preferred = acceptLang.split(',')[0].split('-')[0].toLowerCase(); if ((SUPPORTED_LOCALES as readonly string[]).includes(preferred)) { targetLocale = preferred as typeof SUPPORTED_LOCALES[number]; } } } // Redirect to the localized path const newUrl = request.nextUrl.clone(); newUrl.pathname = `/${targetLocale}${pathname === '/' ? '' : pathname}`; return NextResponse.redirect(newUrl); } // Next.js 16 Proxy configuration export const config = { matcher: [ /* * Match all request paths except for the ones starting with: * - api (API routes) * - _next/static (static files) * - _next/image (image optimization files) * - favicon.ico, sitemap.xml, robots.txt (metadata files) */ '/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)', ], };