问题描述

博客搜索功能存在概率性 404 问题:

  • 文章设置了 slug 字段(如 ai-voice-input
  • 理论访问链接为 https://blog.brmys.cn/ai-voice-input
  • 但通过搜索、左侧文件夹点击进入时,概率性显示 404

问题根因

contentIndex.json 索引结构

contentIndex.json 使用原始文件名作为索引键:

{
  "AI语音输入,比打字快4倍": {
    "slug": "AI语音输入,比打字快4倍",
    "canonicalSlug": "ai-voice-input",
    ...
  }
}

搜索组件问题

search.inline.ts 中的 formatForDisplay 函数返回的是**原始 slug(文件名)**而非 canonicalSlug

// 修复前
const formatForDisplay = (term: string, id: number) => {
  const slug = idDataMap[id]  // 这是原始文件名
  return {
    slug,  // 导致链接指向文件名而非 canonicalSlug
    ...
  }
}

链接生成问题

resolveUrl 函数使用相对路径,在某些情况下会导致路径拼接错误。

修复方案

1. 修改 formatForDisplay 函数

文件: quartz/components/scripts/search.inline.ts:266-278

const formatForDisplay = (term: string, id: number) => {
  const slug = idDataMap[id]
  const contentDetails = data[slug]
  // 使用 canonicalSlug(如果存在),否则使用原始 slug
  const targetSlug = (contentDetails.canonicalSlug || slug) as FullSlug
  return {
    id,
    slug: targetSlug,  // 现在返回 canonicalSlug
    title: searchType === "tags" ? contentDetails.title : highlight(term, contentDetails.title ?? ""),
    content: highlight(term, contentDetails.content ?? "", true),
    tags: highlightTags(term.substring(1), contentDetails.tags),
  }
}

2. 修改 resolveUrl 函数

文件: quartz/components/scripts/search.inline.ts:296-299

function resolveUrl(slug: FullSlug): URL {
  // 确保使用绝对路径,避免相对路径问题
  return new URL("/" + slug, location.origin)
}

3. 清理未使用的代码

  • 删除未使用的 resolveRelative 导入
  • 删除 setupSearch 函数的 currentSlug 参数
  • 删除 nav 事件监听器中未使用的 e 参数

修复效果

修复前流程

用户搜索 "AI语音输入"
→ 返回 slug: "AI语音输入,比打字快4倍"
→ 生成链接 /AI语音输入,比打字快4倍
→ 404(实际页面在 /ai-voice-input)

修复后流程

用户搜索 "AI语音输入"
→ 返回 slug: "AI语音输入,比打字快4倍"
→ 读取 canonicalSlug: "ai-voice-input"
→ 生成链接 /ai-voice-input
→ 成功访问

提交信息

commit 9a9befd6
修复搜索结果点击 404 问题

- formatForDisplay 函数现在使用 canonicalSlug 而非原始 slug
- resolveUrl 函数改用绝对路径,避免相对路径拼接问题
- 移除未使用的 currentSlug 参数和 resolveRelative 导入

相关文件

  • quartz/components/scripts/search.inline.ts - 搜索组件客户端脚本
  • quartz/plugins/emitters/contentIndex.tsx - 内容索引生成器
  • quartz/plugins/transformers/frontmatter.ts - Frontmatter 解析(slug_short 来源)