Skip to content

Commit 916a6e8

Browse files
fix(seo): 修复排行榜链接全 404 + 补段化前旧 URL 的 301
排行榜每条链接都 404:generate-leaderboard 从文件路径手拼 URL,没跟上 2026-05 的 i18n 段化——少 /zh|/en 前缀、保留 .en/.zh 后缀和 /index、leetcode 没拼音化。重写 buildCanonicalDocUrl 产出真实 canonical:按后缀选 locale 前缀、 去 /index、leetcode 按题号指向英文版 /en(中文翻译文件名经 fumadocs 解析后 slug 不可预测,英文 ASCII slug 一定 200),并过滤内容树里已不存在的孤儿 docId 死链。dev server 实测 153/153 链接全部 200(原 0/153)。 GSC 上百条 .en/.zh 后缀旧 URL(最大一类 404):在 next.config redirects 补 301 (必须放这而非 proxy.ts——proxy matcher 排除带点路径,.en/.zh 后缀全带点碰不到 中间件)。含 .en/.zh 后缀剥离、/index 剥离、裸 /computer-science 映射、no-locale /docs 兜底。六类重定向 curl 实测均单跳 301 到正确 canonical。 脚本因导入 lib/leetcode-slug.ts 改用 node 跑 .mts(tsx 在 Node 24 下解析 .ts 具名导出报错),prebuild 同步改。
1 parent d21f336 commit 916a6e8

5 files changed

Lines changed: 1742 additions & 935 deletions

File tree

dev_docs/i18n_url_routing.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,36 @@ languages:
280280

281281
`disallow` 用 wildcard 形式 `/*/admin/` 等匹配两种 locale 前缀。
282282

283+
### 段化前旧 URL 的 301(`.en` / `.zh` 后缀)
284+
285+
段化前 locale 是**文件后缀**`/docs/foo.en``/docs/bar.zh`),段化后变成
286+
**URL 段前缀**`/en/docs/foo`)。GSC 里还存着上百条 `.en`/`.zh` 旧 URL,是最大
287+
一类 404。重定向规则放在 **`next.config.mjs``redirects()`**,不是 `proxy.ts`
288+
289+
> `proxy.ts` 的 matcher 排除了 `.*\..*`(任何带点路径都不进中间件),而 `.en`/
290+
> `.zh` 后缀全带点 → 中间件根本碰不到。`next.config``redirects()` 跑在路由层,
291+
> 不受该排除影响,是带点旧 URL 唯一能 301 兜住的地方。
292+
293+
规则顺序敏感(首匹配命中):`.en`/`.zh` 后缀剥离 + `/index` 剥离排在 IA wildcard
294+
之前;末尾一条 no-locale `/docs/:path*``/zh/docs/:path*` 兜底(段化后 canonical
295+
必带 locale 前缀,任何裸 `/docs/...` 都是旧链接)。`:slug(.*)\\.en` 用贪婪捕获吃掉
296+
`/` 的多级路径,结尾 `\.en` 做字面锚定。
297+
298+
### 排行榜 / 热榜链接的 canonical URL
299+
300+
`scripts/generate-leaderboard.mts` 从后端 docId 反查 `.source` 文件路径拼 URL。
301+
段化后必须产出 `/<locale>/docs/<slug>`,否则排行榜每条链接都 404。`buildCanonicalDocUrl`
302+
做三件事和路由对齐:① 剥 `.en`/`.zh` 后缀并据此选 locale 前缀;② 去 `/index`
303+
③ leetcode 走特殊处理。
304+
305+
**leetcode 的坑**:同一题常有英文版(`1234-xxx.en.md`)+ 中文翻译版
306+
`1234. 中文_translated.md` / `[121]中文_translated.md`)。中文文件名经 fumadocs
307+
i18n 解析后的真实 slug **不可预测**——带 `. ` 点空格的会塌缩、带方括号的能独立成
308+
拼音页,手搓拼音对不齐(`proxy.ts` 的 leetcode slug-map 也踩同样的坑)。而英文文件的
309+
ASCII slug 一定能解析、且只在 `/en` 渲染(`.en.md`,zh 不回退 en)。所以脚本按**题号**
310+
把任何 leetcode 贡献指向英文版 `/en/docs/.../<ascii-slug>`(保证 200),无英文兄弟时
311+
才退回 zh 拼音。改 leetcode 文件命名后,这套靠 `pnpm build` 重新生成。
312+
283313
## proxy 流程
284314

285315
每个请求 → `proxy.ts`

0 commit comments

Comments
 (0)