长尾内容站规划:分类、slug、内链做成数据撑 500 篇

把分类、slug、内链都做成数据,让长尾内容站从 1 篇撑到 500 篇都不用大改架构。含内容表模板和 slug 强校验。

长尾站靠累计大量小查询取胜。但只有结构在 50 篇之前就规划好——分类写进 schema、slug 由正则强校验、内链策略由脚本审计——才能赢。

问题背景

长尾站不是”一个博客发很多帖子”。它是一个结构化的内容数据库:每篇文章打一个具体查询,内链围绕 pillar 主题聚合,URL 和分类结构告诉搜索引擎这个站到底是干什么的。第一天把这些规划好多花一个周末;写了 200 篇再回头改可能要花一个月。

判断标准

  • 已经验证过这个方向至少有 200 个不同的长尾查询。
  • 主题天然能拆成 4-8 个共享受众但问题不同的子方向。
  • 能一句话说清楚自己和前三名竞品的差异。
  • 有现实的产出节奏(每周 1-3 篇,能持续 9 个月以上)。
  • 能承诺一种永远不改的 slug 规范。

快速结论

第一篇之前定好子主题分类和 slug 规则,第 20 篇之前定好内链策略。这两件事后面几乎不可能重构。

开始前准备

  • 至少 200 个候选长尾 query 已识别(见 judge-search-demand-before-building)。
  • 4-8 个 hub 列表草拟好。
  • slug 正则已选好并冻结。

实操步骤

  1. 方向拆成 4-8 个 hub。 每个 hub 至少能规划出 20 个长尾子题。hub 列表写进内容 schema 防 typo:
// src/content/config.ts
const HUBS = ['indie-dev', 'ai-tools', 'prompt-library',
              'troubleshooting', 'ai-applications'] as const;

schema: z.object({
  // ...
  category: z.enum(HUBS),
  primaryKeyword: z.string().min(3),
  targetQuery: z.string().optional(),  // 这篇为之存在的长尾短语
  pillar: z.string().optional(),
}),
  1. 选定 slug 规范并冻结。 kebab-case、不带日期、不带分类前缀。schema 正则强校验:
urlSlug: z.string().regex(/^[a-z0-9][a-z0-9-]{2,80}[a-z0-9]$/, 'kebab-case only')

CI 里再禁日期前缀:

ls src/content/articles/zh/*/ | grep -E '^[0-9]{4}-' && echo "FAIL: slug 带日期" && exit 1
  1. URL 结构选好。 扁平(/articles/slug/)以后好重构;嵌套(/hub/slug/)主题信号更强但锁死。独立站默认扁平。选一次写进 CONTENT.md

  2. 内容计划做成数据,不是 Trello。 每个 hub 一个 CSV 或 YAML:

slug,hub,targetQuery,pillar,status,publishedAt,linksTo,linksFrom
firebase-custom-domain,indie-dev,firebase 自定义域名,firebase-hosting-go-live-checklist,published,2026-05-17,"firebase-cache-and-deploy-update;what-is-firebase-hosting",firebase-hosting-go-live-checklist
firebase-cache-and-deploy-update,indie-dev,firebase 缓存,firebase-hosting-go-live-checklist,published,2026-05-17,"firebase-custom-domain",firebase-route-404-causes
# ...
  1. pillar 后写。 先发 5-7 篇 cluster;从中沉淀出 pillar。每个 hub 一篇 pillar。

  2. 内链是硬规则。 每篇新文至少链 2 篇老文,至少 1 篇老文反链。prebuild 强制:

// scripts/check-internal-link-density.mjs(节选)
import { readFileSync } from 'node:fs';
const md = readFileSync(file, 'utf8');
const outLinks = (md.match(/\]\(\/[a-z]+\/articles\//g) || []).length;
if (outLinks < 2) {
  console.error(`内链太薄: ${file} 只有 ${outLinks} 条`);
  process.exit(1);
}
  1. sitemap 按深度分 priority。 pillar 0.8、cluster 0.6、标签 0.3——给爬虫提示:
// astro.config.mjs
sitemap({
  serialize(item) {
    if (item.url.includes('/category/')) item.priority = 0.8;
    else if (item.url.includes('/articles/')) item.priority = 0.6;
    else if (item.url.includes('/tag/')) item.priority = 0.3;
    return item;
  },
}),
  1. 每 30 天复盘。 拉 Search Console pages 报告,曝光 < 5 的标记待刷新,把真实出现的新长尾 query 补进计划:
curl -X POST "https://www.googleapis.com/webmasters/v3/sites/$SITE/searchAnalytics/query" \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  --data '{"startDate":"2026-04-22","endDate":"2026-05-22",
           "dimensions":["query","page"],"rowLimit":500}' \
  | jq -r '.rows[] | [.clicks,.impressions,.keys[0],.keys[1]] | @tsv' \
  | sort -k2 -rn | head -30

执行检查清单

  • hub 在 schema 里是 enum
  • slug 正则强制 kebab-case 且禁日期前缀。
  • 内容计划是 CSV/YAML,不是只在脑子里。
  • prebuild 在内链过薄时挂构建。
  • sitemap priority 反映 pillar vs cluster。

上线后验证

  • 60 天后每篇 cluster 都至少被 1 篇 pillar 链入并自身链出 2 篇。
  • 没有孤儿文章(audit-pillars.mjs 验证)。
  • Search Console “Discovered – currently not indexed” 保持在 10% 以下。

容易踩的坑

  • 跳过分类直接想到啥写啥,最后变成 100 篇孤儿文章。
  • slug 里加日期(/2026-how-to-...),内容更新时被迫重写。
  • URL 嵌套太深(/cat/sub/sub/slug/),改分类就死链。
  • 内链规则还没建立就让 AI 一口气生成 50 篇。
  • 把”长尾”当成”低质”理由发薄稿——2026 年的 Google 在长尾领域也读得出薄。
  • 内容计划在 Trello 没有导出——300 张卡之后就 grep 不动了。

FAQ

  • 写多少篇能看到流量: 2026 年常见的数字是 40-60 篇结构良好、相互内链的文章,前提是方向合适、站点上线 4 个月以上。
  • 扁平还是嵌套 URL: 独立站推荐扁平,hub 可以随时调整而不破链。除非你的 hub 真的永久不变,再考虑嵌套。
  • 能不能用 AI 写初稿: 你完全懂的主题可以;你没法 fact-check 的主题坚决不行。无论哪种都需要人工编辑。
  • 什么时候在分类之上加标签系统: 大概 100 篇之后、读者需要分类之外的横向切分时。更早加就是过度设计。
  • 内容计划放 Notion / Airtable / 仓库?: 仓库。content-plan/ 下 CSV 或 YAML。要 grep 得动、diff 得了、脚本能读。

相关阅读

标签: #独立开发 #建站策划 #长尾词 #SEO #Pillar / Cluster #内容运营