import { NextRequest, NextResponse } from 'next/server'; import { locales, defaultLocale } from './lib/i18n'; export function middleware(request: NextRequest) { // 在静态导出模式下,中间件不会执行 // 这个文件保留用于开发和服务器模式 // 在静态导出模式下跳过中间件逻辑 if (process.env.NODE_ENV === 'production' && process.env.NEXT_OUTPUT_MODE === 'export') { return NextResponse.next(); } const pathname = request.nextUrl.pathname; // Check if there is any supported locale in the pathname const pathnameIsMissingLocale = locales.every( (locale) => !pathname.startsWith(`/${locale}/`) && pathname !== `/${locale}`, ); // Redirect if there is no locale if (pathnameIsMissingLocale) { // Get locale from Accept-Language header or use default const locale = getLocaleFromRequest(request) || defaultLocale; // Don't redirect for default locale on root path if (locale === defaultLocale && pathname === '/') { return NextResponse.next(); } // Redirect to locale-prefixed path for non-default locales if (locale !== defaultLocale) { return NextResponse.redirect( new URL(`/${locale}${pathname === '/' ? '' : pathname}`, request.url), ); } } return NextResponse.next(); } function getLocaleFromRequest(request: NextRequest): string | undefined { // Get locale from cookie first const localeCookie = request.cookies.get('locale')?.value; if (localeCookie && locales.includes(localeCookie as any)) { return localeCookie; } // Get locale from Accept-Language header const acceptLanguage = request.headers.get('accept-language'); if (acceptLanguage) { const preferredLocale = acceptLanguage .split(',') .map((lang) => lang.split(';')[0].trim()) .find((lang) => locales.includes(lang as any)); if (preferredLocale) { return preferredLocale; } } return defaultLocale; } export const config = { matcher: [ // Skip all internal paths (_next), static files, and manifest files '/((?!_next|api|favicon.ico|site.webmanifest|.*\\..*).*)', ], };