中间件

基于用户偏好的自动语言检测与 URL 路由

Middleware 会自动检测用户的语言偏好,并将其重定向到站点对应的本地化版本。 它会使用浏览器设置、地理位置以及用户偏好,在任何内容加载之前就提供正确的语言版本。

文件位置:proxy.ts 放在项目根目录中,与 app/ 目录处于同一层级,而不是放在 app/ 目录内。proxy.ts(Next.js 16+)或 middleware.ts(Next.js 15 及以下)

设置

步骤 1:创建动态路由

app/ 文件夹下创建一个 [locale] 目录,并将所有页面移动到该目录中:

proxy.ts
layout.tsx
page.tsx
next.config.js

步骤 2:添加中间件

在项目根目录下创建 proxy.ts

import { createNextMiddleware } from 'gt-next/middleware';

export default createNextMiddleware();

export const config = {
  // 匹配所有路径,但排除 API 路由、静态文件和 Next.js 内部路径
  matcher: ['/((?!api|static|.*\\..*|_next).*)']
};

从而实现自动语言检测以及带有 locale 前缀的 URL 路由,例如 /en/about/es/about

语言检测

中间件按以下顺序检测用户的语言偏好:

  1. URL locale - /es/about → 西班牙语
  2. 用户 Cookie - 先前的语言选择
  3. 浏览器请求头 - Accept-Language
  4. 默认 locale - 配置的 fallback 语言

中间件会自动完成浏览器语言检测并持久化 Cookie,无需额外配置。

本地化路径

为不同语言自定义 URL 路径:

export default createNextMiddleware({
  pathConfig: {
    // 英文:/en/products;中文:/zh/产品
    "/products": {
      "zh": "/产品"
    },
    
    // 动态路由:/en/product/123;/zh/产品/123
    "/product/[id]": {
      "zh": "/产品/[id]"
    }
  }
});

URL 结构

默认情况下,你的默认 locale 将不会带有语言代码前缀:

/about     → /about        (默认 locale:英语)
/about     → /es/about     (西班牙语)
/about     → /fr/about     (法语)

为默认 locale 添加前缀

若要为所有 locale(包括默认)添加前缀:

export default createNextMiddleware({
  prefixDefaultLocale: true
});

结果:

/about     → /en/about     (英语,带前缀)
/about     → /es/about     (西班牙语,带前缀)
/about     → /fr/about     (法语,带前缀)

常见问题

缺少动态路由

所有页面必须放在 [locale]/ 目录下:

❌ 错误示例:
app/
├── page.tsx
└── about/page.tsx

✅ 正确示例:
app/
└── [locale]/
    ├── page.tsx
    └── about/page.tsx

匹配器配置

排除 API 路由和静态文件:

export const config = {
  matcher: ['/((?!api|static|.*\\..*|_next).*)']
};

彻底测试你的 middleware 配置——不正确的匹配器可能导致无限重定向,或导致静态资源无法正常加载。

后续步骤

本指南如何?