首页›文章›中文技术站 SEO 实战:canonical、sitemap 与中文 slug

中文技术站 SEO 实战:canonical、sitemap 与中文 slug

计算机技术 · web 开发2026-09-193次浏览0 个评论

本篇是《手写一个内容型技术博客站》系列第 9 篇。

技术博客 SEO 的价值在于长尾流量——一篇认真的教程可以持续几年被搜到。这篇讲内容站 SEO 最容易忽视也最容易出事的三块:页面级 canonical/OG、sitemap 与 RSS、中文 slug。

一、页面级 SEO 字段:一个"全站 canonical 都指向首页"的坑

症状

社交平台分享某篇文章时,预览卡片全指向首页;搜索引擎把整站当重复内容。

根因

页面只设置了 title/description,而 openGraph 和 alternates.canonical 全部继承了 layout.tsx 的全站默认值。于是:

html
<!-- 每篇文章都这样:canonical 指向首页! -->
<link rel="canonical" href="https://chahuawu.com">
<meta property="og:url" content="https://chahuawu.com">
  • 搜索引擎:几十个页面 canonical 都指向 https://chahuawu.com → 判定重复内容,只索引首页
  • 社交分享:og:url 是首页 → 分享卡片不指向文章

修法:统一出口 pageMetadata

让每个页面的 metadata 都带页面级 canonical + OG,收敛到一个函数:

ts
// src/lib/seo.ts
// 各 page.tsx 的 generateMetadata 里调用,扫尾补 canonical + OG + twitter
export function pageMetadata({
  title,
  description,
  path,   // 页面相对路径,如 /posts/my-article
  type,   // "article" | "website"
}) {
  return {
    title,
    description,
    alternates: { canonical: path },          // 结合 metadataBase 转绝对 URL
    openGraph: { title, description, url: path, type },
    twitter: { card: "summary_large_image" },
  };
}

约定:新增页面 metadata 必须走 pageMetadata,不要手写裸 return {title, description}——那会漏 canonical/OG 掉回首页默认。

验证

build 后直接 grep 产物:

bash
grep -r 'rel="canonical"' .next/server/app/**/*.html
# 应为每页各自的 URL,而不是 chahuawu.com 首页

二、SSG + ISR:sitemap 与 RSS 的增量重建

sitemap / RSS / robots 都是 ISR(revalidate=600):

ts
// src/app/sitemap.ts
export const revalidate = 600; // 内容变动后最多 10 分钟自动重建

export default function sitemap(): MetadataRoute.Sitemap {
  // 遍历:文章(categories)+ 教程 + 静态页
  // 返回 { url, lastModified } 列表
}

ISR 的意义:新增一篇文章不必跑完整 build 才更新 sitemap——10 分钟内自动重建。注意它不会重新枚举 generateStaticParams(本系列第 8 篇讲过),但 sitemap 这类"读全量再输出"的路由不受此限,是 ISR 的合适场景。

RSS 的一个坑:image 别用跳转链接

ts
// rss.xml 的 <image><url>
// 错误:用 qrcode.href(那是跳转链接,不是图片 URL)
// 正确:用默认 OG 图 getDefaultOgImage()

种子阅读器抓 <image><url> 当站标图,给了跳转链接会显示失败或不显示。站标图要用真实图片 URL。

三、JSON-LD 结构化数据

给搜索引擎机器可读的语义:

jsx
// src/components/JsonLd.tsx
<script type="application/ld+json">
  {/* WebSite schema(全站 layout)
      Article schema(文章详情页,含 headline/datePublished/author/image) */}
</script>
  • WebSite:全站注入(layout 层)
  • Article:文章详情页注入(headline/datePublished/author/mainEntityOfPage)

结构化数据的好处:搜索结果展示更丰富(作者、日期、面包屑),是低成本高回报的 SEO 项。

四、OG 分享图

让社交分享有图:public/og-default.png(1200x630),pageMetadata 自动加 openGraph.images + twitter.card=summary_large_image。

尺寸 1200x630 是主流社交平台的标准(Twitter/X、微信、LinkedIn)。生成可以用 Python PIL 脚本出渐变底+站名+slogan。

五、中文 slug 的三个注意点

这是中文技术站特有的坑。

1. 必须有英文 slug,不能靠中文文件名兜底

无 frontmatter slug 时,categories.ts 会回调文件名 slug: data.slug || 文件名。中文文件名会被直接当 URL slug——Next 对中文动态段 SSG 匹配会 404。

修法:给中文标题的文章写英文 frontmatter slug:

yaml
title: 实践论 - 论认识和实践的关系
slug: shijianlun

2. 拼音分词:不要生成粘连 slug

中文标题转 slug 的标准做法是分词后逐词转拼音,而不是整串拼:

text
手工更新drupal core  →  shougong-gengxin-drupal-core   ✅
手工更新drupal core  →  shougonggengxindrupal-core      ❌ 粘连

用 jieba 分词 + lazy_pinyin 逐词转。slug 只改 frontmatter 不改文件名 → commentId(基于文件路径 md5)不变,评论/阅读数不丢。

3. 校验要兼容存量大写 slug

slug 安全字符白名单要含大写(^[A-Za-z0-9][A-Za-z0-9-]*$)——存量 Hermes-Agent-Hindsight-configuration 这种含大写 slug 一直在正常访问,校验过严会误报(本系列第 7 篇详述)。

4. 改动 slug 的连带提醒

slug 变了 → URL 变了 → 旧链接 404。改 slug 交付时务必提醒:重建 + 重启生产生效;外部收藏/搜索直达的旧 URL 会 404(除非做 301 重定向,否则接受)。

六、SEO 检查清单

text
□ 每页 canonical/OG 指向自身(非首页)——统一走 pageMetadata
□ sitemap/RSS/robots 用 ISR(revalidate=600)
□ RSS image 用真实图片 URL(非跳转链接)
□ 文章页注入 Article JSON-LD
□ OG 图 1200x630 存在且被引用
□ 中文标题文章有英文 slug(不能靠中文文件名兜底)
□ slug 白名单兼容大写
□ 域名在 site.yaml 配置(sitemap/RSS/OG 绝对链接用)

SEO 的门槛不在"堆关键词",而在基础设施正确——canonical 不重复、sitemap 及时、结构化数据完整。这几点做对,内容自然会被索引得更好。


给普通人的一句话:搜索引擎看的是"你网站的地址是否清晰、每页是不是独立、更新是否及时"——把这些做对,内容好就会有人来。

参考

  • Next.js Metadata:https://nextjs.org/docs/app/building-your-application/optimizing/metadata

评论

0

评论加载中…

发表评论

0/2000