mirror of
https://github.com/labring/FastGPT.git
synced 2026-03-21 01:07:59 +08:00
* cloud doc * doc refactor * doc move * seo * remove doc * yml * doc * fix: tsconfig * fix: tsconfig
106 lines
4.1 KiB
TypeScript
106 lines
4.1 KiB
TypeScript
import { createI18nMiddleware } from 'fumadocs-core/i18n';
|
|
import { i18n } from '@/lib/i18n';
|
|
import { type NextRequest, NextResponse } from 'next/server';
|
|
|
|
// Old path redirects mapping
|
|
const exactMap: Record<string, string> = {
|
|
'/docs': '/docs/introduction',
|
|
'/docs/intro': '/docs/introduction',
|
|
'/docs/guide/dashboard/workflow/coreferenceresolution':
|
|
'/docs/introduction/guide/dashboard/workflow/coreferenceResolution',
|
|
'/docs/guide/admin/sso_dingtalk':
|
|
'/docs/introduction/guide/admin/sso#/docs/introduction/guide/admin/sso#钉钉',
|
|
'/docs/guide/knowledge_base/rag': '/docs/introduction/guide/knowledge_base/RAG',
|
|
'/docs/commercial/intro': '/docs/introduction/commercial',
|
|
'/docs/upgrading/intro': '/docs/self-host/upgrading/upgrade-intruction',
|
|
'/docs/upgrading': '/docs/self-host/upgrading/upgrade-intruction',
|
|
'/docs/introduction/shopping_cart/intro/': '/docs/introduction/commercial',
|
|
'/docs/introduction/cloud': '/docs/introduction/cloud/intro',
|
|
'/docs/protocol/terms': '/docs/introduction/cloud/terms',
|
|
'/docs/protocol/privacy': '/docs/introduction/cloud/privacy',
|
|
'/docs/introduction/development/docker': '/docs/self-host/deploy/docker',
|
|
'/docs/introduction/development/sealos': '/docs/self-host/deploy/sealos',
|
|
'/docs/introduction/development/intro': '/docs/self-host/dev',
|
|
'/docs/introduction/development/object-storage': '/docs/self-host/config/object-storage'
|
|
};
|
|
|
|
const prefixMap: Record<string, string> = {
|
|
'/docs/FAQ': '/docs/faq',
|
|
'/docs/guide': '/docs/introduction/guide',
|
|
'/docs/shopping_cart': '/docs/introduction/shopping_cart',
|
|
'/docs/upgrading': '/docs/self-host/upgrading',
|
|
'/docs/development': '/docs/self-host',
|
|
'/docs/introduction/development/openapi': '/docs/openapi',
|
|
'/docs/introduction/development': '/docs/self-host'
|
|
};
|
|
|
|
const i18nMiddleware = createI18nMiddleware(i18n);
|
|
|
|
export default function middleware(request: NextRequest) {
|
|
const { pathname } = request.nextUrl;
|
|
|
|
// Extract language from pathname
|
|
let lang = i18n.defaultLanguage;
|
|
let pathWithoutLang = pathname;
|
|
|
|
for (const language of i18n.languages) {
|
|
if (pathname.startsWith(`/${language}`)) {
|
|
lang = language;
|
|
pathWithoutLang = pathname.slice(`/${language}`.length);
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Check exact match redirects
|
|
if (exactMap[pathWithoutLang]) {
|
|
const newUrl = new URL(`/${lang}${exactMap[pathWithoutLang]}`, request.url);
|
|
return NextResponse.redirect(newUrl, 301);
|
|
}
|
|
|
|
// Check prefix match redirects
|
|
for (const [oldPrefix, newPrefix] of Object.entries(prefixMap)) {
|
|
if (pathWithoutLang.startsWith(oldPrefix)) {
|
|
const rest = pathWithoutLang.slice(oldPrefix.length);
|
|
const newUrl = new URL(`/${lang}${newPrefix}${rest}`, request.url);
|
|
return NextResponse.redirect(newUrl, 301);
|
|
}
|
|
}
|
|
|
|
// Check if URL has a language prefix
|
|
const hasLangPrefix = i18n.languages.some(
|
|
(l) => pathname.startsWith(`/${l}/`) || pathname === `/${l}`
|
|
);
|
|
|
|
if (hasLangPrefix) {
|
|
// Save user's language preference to cookie when visiting a localized URL
|
|
const currentCookie = request.cookies.get('FD_LOCALE')?.value;
|
|
if (currentCookie !== lang) {
|
|
// @ts-expect-error - Fumadocs middleware signature mismatch
|
|
const response = i18nMiddleware(request) ?? NextResponse.next();
|
|
// @ts-ignore
|
|
response.cookies.set('FD_LOCALE', lang, {
|
|
path: '/',
|
|
maxAge: 60 * 60 * 24 * 365
|
|
});
|
|
return response;
|
|
}
|
|
} else {
|
|
// No language prefix — check cookie for user's language preference
|
|
const cookieLocale = request.cookies.get('FD_LOCALE')?.value;
|
|
if (cookieLocale && i18n.languages.includes(cookieLocale)) {
|
|
const newUrl = new URL(`/${cookieLocale}${pathname}`, request.url);
|
|
newUrl.search = request.nextUrl.search;
|
|
return NextResponse.redirect(newUrl);
|
|
}
|
|
}
|
|
|
|
// Continue with i18n middleware (falls back to Accept-Language detection)
|
|
// @ts-expect-error - Fumadocs middleware signature mismatch
|
|
return i18nMiddleware(request);
|
|
}
|
|
|
|
export const config = {
|
|
matcher: [
|
|
'/((?!api|_next/static|_next/image|favicon.ico|robots\\.txt|sitemap.*\\.xml|.*\\.svg|.*\\.png|deploy/.*).*)']
|
|
};
|