CloudTech/middleware.ts
2025-09-16 18:00:27 +08:00

65 lines
2.2 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
const locales = ['zh-CN', 'zh-TW', 'en'];
const defaultLocale = 'zh-CN';
// 获取首选语言
function getLocale(request: NextRequest): string {
// 1. 检查URL路径中是否已包含语言代码
const pathname = request.nextUrl.pathname;
const pathnameIsMissingLocale = locales.every(
(locale) => !pathname.startsWith(`/${locale}/`) && pathname !== `/${locale}`
);
if (!pathnameIsMissingLocale) {
return locales.find(locale => pathname.startsWith(`/${locale}`)) || defaultLocale;
}
// 2. 检查Accept-Language头
const acceptLanguage = request.headers.get('accept-language');
if (acceptLanguage) {
const preferredLocale = locales.find(locale =>
acceptLanguage.toLowerCase().includes(locale.toLowerCase())
);
if (preferredLocale) {
return preferredLocale;
}
}
return defaultLocale;
}
export function middleware(request: NextRequest) {
const pathname = request.nextUrl.pathname;
// 检查路径是否已经包含语言代码
const pathnameIsMissingLocale = locales.every(
(locale) => !pathname.startsWith(`/${locale}/`) && pathname !== `/${locale}`
);
// 如果路径缺少语言代码,则重定向
if (pathnameIsMissingLocale) {
const locale = getLocale(request);
return NextResponse.redirect(
new URL(`/${locale}${pathname.startsWith('/') ? '' : '/'}${pathname}`, request.url)
);
}
}
export const config = {
// 匹配所有路径除了api、_next/static、_next/image、favicon.ico等
matcher: [
/*
* 匹配所有请求路径,除了以下开头的:
* - api (API routes)
* - _next/static (静态文件)
* - _next/image (图片优化文件)
* - favicon.ico (网站图标)
* - locales (翻译文件)
* - docs (文档文件)
* - 各种静态资源文件
*/
'/((?!api|_next/static|_next/image|favicon.ico|locales|docs|.*\\.png$|.*\\.jpg$|.*\\.jpeg$|.*\\.gif$|.*\\.svg$|.*\\.ico$|.*\\.css$|.*\\.js$|.*\\.json$|.*\\.md$).*)',
],
};