当前位置: 首页 > article >正文

Next.js 多语言 (1) | 中间件(Middleware)的设置与应用

当我们开发一个支持多语言的 Next.js 网站时,常常需要解决以下问题:

  • 用户首次访问时,应该显示哪个语言版本? 🤔
    比如,用户访问 / 时,是展示 /en 还是 /de

  • SEO 是否能够抓取所有语言版本的页面? 🔍
    搜索引擎如何识别 /en/de,并在搜索结果中正确展示?

  • 中间件是否会干扰静态资源的加载? 🚧
    比如 /favicon.ico/_next 这样的资源路径是否会被错误地处理?

  • 访问未带前缀的页面是否需要跳转? 🧭
    比如用户访问 /blog/123 时,是否应该自动跳转到 /en/blog/123/zh-CN/blog/123
    这些问题的核心都与 中间件(Middleware) 的配置密切相关。如果中间件设置不当,不仅会影响用户体验,还会导致搜索引擎抓取异常,最终影响网站的 SEO 表现。

本篇文章将通过案例为你详细解析这些问题,并手把手教你如何配置中间件,让多语言网站更加智能 🌟、高效 🚀 且 SEO 友好 💡。


问题 1:用户首次访问时,应该显示哪个语言版本?

问题背景

当用户访问网站的根路径 / 时,他们希望直接进入自己的偏好语言页面(比如 /zh 中文版)。如果默认跳转到 /en(英文版),可能会让不熟悉英文的用户感到困惑,降低用户体验。

那么问题来了:如何在用户首次访问时,自动检测并跳转到他们期望的语言页面呢?

中间件的解决方案:语言检测逻辑

中间件通过以下优先级,动态检测用户的语言:

  1. 路径前缀(最高优先级)
    如果用户访问路径中包含语言前缀(如 /en/about/zh/about),中间件会直接使用该语言。
  2. Cookie
    中间件会检查是否存在 NEXT_LOCALE Cookie,这个 Cookie 会保存用户之前选择的语言。例如,如果用户上次访问了 /zh,中间件会自动记住并再次跳转到 /zh
  3. 浏览器语言头
    如果路径和 Cookie 中都没有语言信息,中间件会读取浏览器的 Accept-Language 请求头,选择最适合的语言。
    例如,浏览器语言头显示用户的首选语言为 zh(中文),中间件会选择中文页面。
  4. 默认语言(最低优先级)
    如果以上条件都无法确定语言,中间件会使用 defaultLocale 中配置的默认语言。比如设置为 en,用户会被跳转到英文页面。
代码示例:语言检测与跳转
// middleware.ts
import createMiddleware from 'next-intl/middleware';

export default createMiddleware({
  locales: ['en', 'zh'], // 支持的语言:英文和中文
  defaultLocale: 'en',  // 默认语言为英文
});

export const config = {
  matcher: ['/', '/(en|zh)/:path*'], // 匹配根路径和带语言前缀的路径
};
实际流程演示
  1. 用户首次访问 /
    • 浏览器的 Accept-Language 请求头为 zh
    • 中间件重定向到 /zh,并设置 Cookie NEXT_LOCALE=zh
  2. 用户再次访问 /
    • 中间件检查 Cookie NEXT_LOCALE,发现值为 zh,直接跳转到 /zh

通过这样的逻辑,我们可以为每位用户提供符合他们偏好的语言页面,极大提升用户体验。


问题 2:SEO 是否能够抓取所有语言版本的页面?

问题背景

对于多语言网站来说,SEO 优化的重点有两个:

  1. 是否能抓取到所有语言版本的页面?
    比如,搜索引擎是否能分别抓取 /en/about(英文版)和 /zh/about(中文版)?
  2. 不同语言页面的关联是否正确?
    如果没有正确配置 hreflang 标签,不同语言页面可能被搜索引擎视为重复内容,从而影响排名。
中间件的解决方案
  1. 为每种语言生成独立路径
    中间件通过路径前缀(如 /en/zh),为每种语言生成独立页面 URL,确保搜索引擎能够抓取到每个版本。
  2. 生成 hreflang 标签
    配置 hreflang 标签,明确指示页面的语言版本关联关系,帮助搜索引擎正确识别。
代码示例:SEO 配置

中间件配置:

// middleware.ts
import createMiddleware from 'next-intl/middleware';

export default createMiddleware({
  locales: ['en', 'zh'], // 支持英文和中文
  defaultLocale: 'en',  // 默认语言为英文
});

export const config = {
  matcher: ['/', '/(en|zh)/:path*'], // 匹配路径
};

Sitemap 配置:

// next-sitemap.config.js
module.exports = {
  siteUrl: 'https://example.com',
  generateRobotsTxt: true,
  alternateRefs: [
    { href: 'https://example.com/en', hreflang: 'en' },
    { href: 'https://example.com/zh', hreflang: 'zh' },
  ],
};
SEO 效果展示
  • /en/about/zh/about 被搜索引擎视为独立页面。
  • hreflang 标签告诉搜索引擎这些页面是不同语言的版本,避免重复内容问题。

问题 3:中间件是否会干扰静态资源的加载?

问题背景

中间件默认会拦截所有请求路径,包括静态资源路径(如 /favicon.ico/_next/static)。如果中间件误处理了这些路径,可能导致:

  • 静态资源无法加载,页面展示异常。
  • 性能下降,因为中间件错误地拦截了无关请求。
中间件的解决方案

通过配置 matcher,明确排除静态资源路径,仅处理与国际化相关的路径。

代码示例:排除静态资源路径
export const config = {
  matcher: [
    '/((?!api|_next|.*\\..*).*)', // 匹配非静态资源路径
    '/([\\w-]+)?/dynamic-route/(.+)', // 显式匹配动态路径
  ],
};
效果展示
  • 路径 /favicon.ico/_next/static 不会被中间件处理。
  • 中间件只针对 /en/zh 等与语言相关的路径生效。

问题 4:访问未带前缀的页面是否需要跳转?

问题背景

在多语言网站中,用户可能直接访问未带语言前缀的路径,例如 /blog/123。这种情况下:

  • 如果网站没有设计无前缀的页面,则需要跳转到对应语言前缀的页面(如 /en/blog/123)。
  • 如果网站支持无前缀的默认语言页面,则可以不跳转,直接展示默认语言内容。

那么问题来了:如何根据需求正确设置页面跳转?


中间件的解决方案:配置跳转逻辑

在中间件中可以通过 matcher 配置对未带前缀的路径进行拦截并自动跳转。例如:

  • 检测用户的语言偏好(Accept-Language 或 Cookie);
  • 重定向到对应语言前缀的页面。
代码示例

以下是一个通用的配置,处理未带前缀的 /blog/... 路径跳转到对应语言页面:

// middleware.ts
import createMiddleware from 'next-intl/middleware';

export default createMiddleware({
  locales: ['en', 'zh-CN', 'zh-HK'], // 支持的语言
  defaultLocale: 'en',              // 默认语言为英文
});

export const config = {
  matcher: [
    '/',
    '/blog/:path*',                 // 未带前缀的博客路径
    '/(en|zh-CN|zh-HK)/:path*',     // 带前缀的其他路径
    '/review',
  ],
};

实际场景演示
  1. 用户访问 /blog/123
    • 中间件会检测用户的语言(例如,Accept-Languagezh-CN)。
    • 跳转到 /zh-CN/blog/123
  2. 用户访问 /blog
    • 如果 Cookie 中记录的语言是 en,则跳转到 /en/blog
  3. 用户访问未匹配的路径:
    • 默认跳转到 /en,或返回 404。

小结

配置跳转逻辑可以实现:

  • 自动将未带语言前缀的页面跳转到带前缀的对应页面;
  • 确保所有页面都有一致的 URL 格式,有助于 SEO 和用户体验。

**总结 **📝

  1. 用户语言的自动检测与跳转
    中间件通过路径前缀、Cookie 和浏览器语言头动态检测语言,并自动跳转到用户期望的页面。
  2. SEO 的多语言支持
    中间件为每种语言生成独立路径,并结合 hreflang 标签,确保搜索引擎正确抓取和展示不同语言页面。
  3. 避免静态资源的干扰
    通过配置 matcher,中间件仅处理国际化相关路径,确保静态资源和其他非国际化路径正常加载。

合理配置中间件,不仅能提升用户体验,还能让你的多语言网站在 SEO 表现上更上一层楼! 🌟


http://www.kler.cn/a/466912.html

相关文章:

  • 数据分析思维(七):分析方法——群组分析方法
  • 【CSS】第一天 基础选择器与文字控制属性
  • Jetpack Compose 学习笔记(四)—— CompositionLocal 与主题
  • SpringMVC(六)拦截器
  • edeg插件/扩展推荐:助力生活工作
  • 【CSS】 ---- CSS 实现图片背景清除的滑动效果三种方法
  • android 开发中的 SPI模式
  • Kotlin 协程与异步编程
  • 《前端web开发-CSS3基础-1》
  • HTML——67. 复选框
  • Linux内核的缺页异常的简介
  • svn 相关应用与管理
  • 生物信息学 笔记
  • OWASP ZAP之API 请求基础知识
  • 克服HTTP无状态难题:专业建议与指导
  • 超越LLaMA:语言模型三重奏Alpaca、Vicuna与WizardLM
  • 用C++使用带头单向非循环链表,实现一个哈西桶
  • 《深入浅出HTTPS​​​​​​​​​​​​​​​​​》读书笔记(25):椭圆曲线密码学(续)
  • ScheduledExecutorService详解
  • SpringBoot 2.6 集成es 7.17
  • 实现图的广度优先遍历(BFS)和深度优先遍历(DFS)
  • Tomcat(116) 如何在Tomcat中解决缓存问题?
  • 因果推断核心算法:倾向得分匹配法PSM
  • Linux(Centos 7.6)命令详解:cd
  • 《Rust权威指南》学习笔记(五)
  • 行业商机信息付费小程序系统开发方案