# gt-next: General Translation Next.js SDK: 中间件 URL: https://generaltranslation.com/zh/docs/next/guides/middleware.mdx --- title: 中间件 description: 根据用户偏好自动进行语言检测并进行 URL 路由 --- 中间件会自动检测用户的语言偏好,并将其重定向到站点对应的本地化版本。 它会在内容加载前根据浏览器设置、地理位置和用户偏好提供正确的语言版本。 App Router 使用 `createNextMiddleware` 进行区域设置路由。Pages Router 则使用 Next.js 内置的 `i18n` 路由和一个 Pages Router 导航回调。 ## Pages Router 区域设置路由 [#pages-router-locale-routing] 不要在 Pages Router 应用中添加 `createNextMiddleware`。请配置 Next.js 内置的区域设置路由,让服务器端渲染和静态生成的页面能够获取当前活动的区域设置。 ### 第 1 步:配置区域设置 将所有受支持的区域设置 (包括默认区域设置) 添加到你的 Next.js 配置中: ```ts title="next.config.ts" import type { NextConfig } from 'next'; import { withGTConfig } from 'gt-next/config'; const nextConfig: NextConfig = { i18n: { locales: ['en', 'es', 'fr', 'ja'], defaultLocale: 'en', }, }; export default withGTConfig(nextConfig); ``` Next.js 对默认区域设置不使用 URL 前缀,而是为其他区域设置添加前缀,例如 `/es/about` 和 `/fr/about`。 ### 第 2 步:在区域设置切换时进行导航 在 `_app.tsx` 中向 `GTProvider` 传入一个导航回调。这样 `LocaleSelector` 就能跳转到所选的 Next.js 区域设置,并加载对应的页面属性: ```tsx title="pages/_app.tsx" import type { AppProps } from 'next/app'; import { useRouter } from 'next/router'; import { GTProvider, type WithGTServerSideProps, type WithGTStaticProps, } from 'gt-next'; type GTPageProps = WithGTServerSideProps | WithGTStaticProps; export default function App({ Component, pageProps, }: AppProps) { const router = useRouter(); const { locale, translations, ...restPageProps } = pageProps; return ( { void router.push( { pathname: router.pathname, query: router.query }, router.asPath, { locale: nextLocale } ); }} > ); } ``` 该回调使用的是 `next/router` 提供的 `useRouter`,也就是 Pages Router 的 API。App Router 应用则使用 `next/navigation` 提供的另一套 API。 对于静态生成的页面,请参照 [Pages Router SSG 说明](/docs/next/guides/ssg#pages-router-setup)。 ## App Router 中间件设置 **文件位置:** 将 `proxy.ts` 放在项目根目录下,与 `app/` 目录同级——不要放在 `app/` 目录内。`proxy.ts` (Next.js 16+) 或 `middleware.ts` (Next.js 15 及以下) ### 第 1 步:创建动态路由 在 `app/` 文件夹中创建一个 `[locale]` 目录,并将所有页面移到其中: ### 第 2 步:添加中间件 在项目根目录下创建 `proxy.ts`: ```ts import { createNextMiddleware } from 'gt-next/middleware'; export default createNextMiddleware(); export const config = { // 匹配除 API 路由、静态文件和 Next.js 内部路径之外的所有路径 matcher: ['/((?!api|trpc|_next|_vercel|.*\\..*).*)'] }; ``` 这会启用自动语言检测,以及使用 `/en/about`、`/es/about` 这类区域设置前缀进行 URL 路由。 如果要将 i18n 中间件限制为仅在选定路径上运行,请在 `withGTConfig` 中配置 [`pathRegex`](/docs/next/api/config/with-gt-config#filter-middleware-paths)。 ## 语言检测 中间件会按以下顺序检测用户的语言偏好: 1. **URL 区域设置** - `/es/about` → 西班牙语 2. **用户 Cookie** - 之前选择的语言 3. **浏览器请求头** - `Accept-Language` 请求头 4. **默认区域设置** - 配置的回退语言 中间件会自动处理浏览器语言检测和 Cookie 持久化,无需额外配置。 ## 本地化路径 为不同语言自定义 URL 路径: ```ts export default createNextMiddleware({ pathConfig: { // 英文:/en/products,中文:/zh/产品 "/products": { "zh": "/产品" }, // 动态路由:/en/product/123,/zh/产品/123 "/product/[id]": { "zh": "/产品/[id]" } } }); ``` ## URL 结构 默认情况下,默认区域设置**不会**带有区域设置代码前缀: ```text /about → /about (默认区域设置:英语) /about → /es/about (西班牙语) /about → /fr/about (法语) ``` ### 为默认区域设置添加前缀 如需为包括默认区域设置在内的所有区域设置添加前缀: ```ts export default createNextMiddleware({ prefixDefaultLocale: true }); ``` 结果: ```text /about → /en/about (English, with prefix) /about → /es/about (Spanish, with prefix) /about → /fr/about (French, with prefix) ``` ## 常见问题 ### 缺少动态路由 所有页面都必须放在 `[locale]/` 下: ```text ❌ Wrong: app/ ├── page.tsx └── about/page.tsx ✅ Correct: app/ └── [locale]/ ├── page.tsx └── about/page.tsx ``` ### 匹配器配置 排除 API 路由和静态文件: ```ts export const config = { matcher: ['/((?!api|trpc|_next|_vercel|.*\\..*).*)'] }; ``` 请务必充分测试你的中间件配置——错误的匹配器可能导致无限重定向,或使静态资源无法正常加载。 ## 后续步骤 **查看实际效果:**[静态站点生成示例应用](https://github.com/gt-examples/static-site-generation)包含完整的中间件 setup 和区域设置路由——[在线预览](https://static-site-generation.generaltranslation.dev)。 * [SSG 指南](/docs/next/guides/ssg) - 基于区域设置路由的静态生成 * [RTL 支持](/docs/next/guides/rtl) - 从右到左书写语言 * API 参考:[`createNextMiddleware()`](/docs/next/api/middleware/create-next-middleware)