⭐️ 继续准备 NextJS 新官网项目(三)

2024-06-28

今天就要准备测试发布新官网项目了,和产品校对后主要发现这个 next-international 多语言库预设的 Middleware 有问题,导致 301 跳转多次。以及因为这个问题,我也没法做好产品另外的一个需求。

  • 需求 1:访问 / 跳转到 /home,如果携带多语言则依旧(例如 /ja 跳转到 /ja/home

    • 无默认首页,只能用 NextResponse.redirect
  • 需求 2:如果系统语言为英语,访问 / 跳转到 /home 而不是 /en/home

    • 需要 NextResponse.rewrite 改写 / 变成 /en 的效果,但前提是系统语言是英语

起初我的实现方案是直接使用该库提供的 urlMappingStrategy 属性,将它设置成 rewriteDefault 可以帮我完成第二个需求,但结果就是发现第一个需求除了我自己跳转了一次,还额外多次跳转了,而且跳转的地址也是极其诡异:

// 启用了 rewriteDefault
/ (307) -> /home (307) -> /ja/home (307) -> /home (307) -> /ja/home (200)

// 未启用
/ (307) -> /home (307) -> /ja/home (200)

通过分析它的 Middleware 源码 可以发现,它其实是获取地址栏语言(假如请求路径是 /ja)之后将路径 307 到 / ,再根据 Cookies 从 / 307 跳转到 /ja 从而完成跳转流程的。由于爬虫不一定会有 Cookies 的概念,于是它这种跳转逻辑,会导致第一次跳转完成后直接 Fallback 成默认语言(可能是英语),最终得到一个 /ja 出现英语页面内容的错误情况。

目前只能去掉这个改写规则暂时发布先,后续看起来只能我自己思考一下怎么自己写一个中间件完成跳转和 Rewrite 了,但我认为这或许是一个 Bug,给作者提一条 Issues 说不定也是可以的?并且我认为我手写的 / 跳转到 /home 而不是检测语言后直接跳转 /ja/home 也不太合理,但这种业务需求肯定不能求着作者帮忙改了...

昨天给 NextJS 提交的那条 Issues 我发现了问题,其实是我阅读有误(当然它文档或许存在一定的易混淆性),next.config.js 它只有 redirects 优先级最高,中间件的 rewrites 就是比 next.config.js 的高,也就是说正确方案或许是直接在中间件里编写对应的 redirects 规则就能够做到反向代理的效果了。

export function middleware(request: NextRequest) {
  if (request.nextUrl.pathname.startsWith("/paul")) {
    const response = NextResponse.rewrite(`https://paul.ren/${request.nextUrl.pathname.replace("/paul", "")}`);

    return response;
  }

  ...
}

新官网上线后,产品还需要增加 Google 统计的代码,看了下 NextJS 官方文档 的做法,它对此做了一个封装,于是我顺藤摸瓜直接模仿它 源码 写了一份(其实又是一个产品的奇葩需求,要求某一个页面添加 2 份统计代码)

多云 烦躁
概览页 时间轴
奇趣音乐盒 技术源于 Kico Player
Emmm,这里是歌词君