做完这篇你能得到什么
AI 公司的训练爬虫默认就会抓取你的内容——如果你用的是 Cloudflare Pages 部署,这件事 Cloudflare 已经自动帮你处理好了,访问你的域名 + /robots.txt 就能验证;同时给文章加上结构化数据,让 Google 更精准地识别文章的发布时间、作者等元数据,有助于在搜索结果里显示日期信息,也有利于被 AI 概述正确引用;另外把图片 alt、标题结构、内链这些容易被忽略的写作细节一次性捋一遍。
前提:已经完成 中级04 里 Search Console 的验证和 sitemap 提交——这篇不会重复这两步,直接往后接。如果还没做,先回那篇走一遍。延续中级04的方向,这篇涉及的所有设置同样是针对 Google 搜索引擎做的,不涉及百度等其他搜索引擎。
给爬虫定规矩:robots.txt
中级04让 Google 知道了"该去哪儿抓",这一步反过来——告诉所有爬虫"哪些地方不该抓"。
如果你用的是 Cloudflare Pages 部署(按这个系列教程做下来都是这种情况),这一步什么都不需要做。 Cloudflare 会在 CDN 层自动注入一份完整的 robots.txt,包含 GPTBot、ClaudeBot、Google-Extended、Bytespider、CCBot、Applebot-Extended、Amazonbot、meta-externalagent 等 AI 训练爬虫的屏蔽规则,不需要任何配置就已经生效了。
直接打开浏览器,访问你的域名 + /robots.txt 验证一下:
|
|
能看到一份带有爬虫屏蔽规则的文件,说明 Cloudflare 已经在帮你处理了。
如果不是从中级04跟下来,未使用 Cloudflare Pages 部署,按照下面步骤操作。
首先Hugo 默认是不生成 robots.txt 文件的,需要手动开启。打开 config/_default/hugo.toml,在文件顶层(不是在 [params] 之类的区块里面)加一行:
|
|
保存,推送到 GitHub:
|
|
等 Cloudflare 重新构建完成后,打开浏览器访问你的域名 + /robots.txt,比如:
|
|


为什么本地访问
http://localhost:1313/robots.txt看不到?hugo server开发模式下不会生成 robots.txt,这是 Hugo 的设计行为,避免开发时误配置影响线上。如果想在本地查看生成结果,运行hugo先构建静态文件,再用type public\robots.txt(Windows)或cat public/robots.txt(Mac/Git Bash)查看public/目录下的文件。
关于
enableRobotsTXT = true这个配置: 对于 Cloudflare Pages 用户,这行不是必须的——不加也已经有完整的 robots.txt 了。如果你加了,必须放在hugo.toml文件的最顶层(不能放在任何[section]区块的后面),否则 Hugo 解析时会把它当成区块内的子配置,导致不生效。
注意区分清楚:
Google-Extended只控制 Google 是否拿你的内容去训练 Gemini 之类的 AI 模型,跟负责把你的网站收进搜索结果的Googlebot是两个完全不同的爬虫,屏蔽前者不会影响你网站在 Google 搜索里的正常收录。这两个名字长得太像,很容易搞混。
如果想屏蔽更多的爬虫,可以在站点根目录创建自己的robots.txt 文件( layouts/robots.txt),然后把规则添加进去。
|
|
如果是跟着教程走下来,使用Cloudflare Pages 部署的,可在Cloudflare的Ai Crawl Control区域,直接管理Robots.txt文件

给 Google 一张"身份证":结构化数据
结构化数据到底是什么:它是写在网页代码里的一段固定格式信息,专门用来告诉搜索引擎"这篇文章的标题是什么、作者是谁、什么时候发布的"。这段信息是给机器读的,不显示在页面上,读者看不到,但搜索引擎能读到。
知道它是什么之后,先破除一个容易误解的说法——你的文章标题、描述、甚至站点导航(精选文章、分类、标签云这些),Google 本来就能从页面里直接抓取并显示在搜索结果里,这不需要任何结构化数据。只要页面结构正常,搜索引擎的基础能力就能做到。
那结构化数据加了什么?关键差别不在"能不能显示内容",而在"Google 理解得有多准确"。打个比方:
没有结构化数据时,Google 看你的页面靠推测——“这段文字大概是标题?这个数字可能是发布日期?",靠算法猜。加了结构化数据,等于你直接在页面代码里明确标注:“这是标题、这是发布时间、这是作者”,不用它猜。
说实话,对刚起步的博客,这一步的即时收益不明显。 基础展示不依赖它,日期显示这种增量效果 Google 也不保证采纳,新站权重低短期更看不出变化。所以如果你时间紧,完全可以先跳过,不影响任何功能。
那为什么还值得做?因为它的价值是长期的,主要在这几个方向:
一是 Google AI 概述(AI Overviews)和各种 AI 搜索,越来越依赖结构化数据来判断"这篇文章谁写的、什么时候写的、可不可信”,这是 2026 年真正在变重要的方向。二是文章标注了作者和日期,长期有利于建立"作者信誉"信号。三是这东西一次配置、全站永久生效,成本极低——属于典型的"低成本、长期收益、短期无感"的投资。
想做的话,往下看;想先跳过也完全没问题。
打开 myblog/layouts/partials/head/custom.html(如果这个文件不存在,先在 layouts/partials/ 下新建 head 文件夹,再建这个文件;(如果你之前因为别的需求已经建过这个文件、里面有内容,那就在已有内容下面另起一行加,别覆盖。)
文件建好后,把下面这段贴进去:
|
|
{{ if .IsPage }} 这一行是为了让这段代码只在文章页生效,首页、归档页这些不需要打上"这是一篇文章"的标签。jsonify 是 Hugo 自带的函数,负责把标题、描述这些文字安全地转成 JSON 格式——直接拿引号包标题,万一标题里本身带了引号或特殊符号,会把整段 JSON 弄坏,用 jsonify 就不用担心这个问题。
这段代码里,绝大部分内容都不用动,照抄就行——唯一需要你手动改的只有 name 这一个字段。 对照下表:
| 字段 | 值 | 要不要改 |
|---|---|---|
headline |
{{ .Title }} |
自动读取文章标题 |
description |
{{ .Description }} |
自动读取 Front Matter 的 description |
datePublished |
{{ .Date... }} |
自动读取文章发布日期 |
dateModified |
{{ .Lastmod... }} |
自动读取文章修改日期 |
url |
{{ .Permalink }} |
自动读取文章网址 |
@context |
https://schema.org |
不用改——固定标识 |
@type |
BlogPosting |
不用改——固定为"博客文章" |
author @type |
Person |
不用改——固定为"人物" |
name |
"你的署名" |
需要改——换成你的名字 |
那些带 {{ }} 的值是 Hugo 模板变量,网站构建时会自动从每篇文章里读取真实内容填进去,你不用管。@context、@type 这些是所有博客文章通用的固定写法。只有作者名 Hugo 没法自动知道,得你写死进去。
比如你叫小布,就把最后改成:
|
|
保存,推送:
|
|
验证 Google 真的看懂了
打开 Google 富媒体结果测试工具,输入刚发布过的一篇文章网址,点检测。等几秒,如果显示检测到 BlogPosting 这个类型,并且列出了标题、发布日期等字段,说明加对了。
如果提示有错误或警告,点开看具体是哪个字段出的问题,回去检查对应的 Front Matter 是不是缺了 description 或者日期格式不对。
写文章时顺手就该做的几件事
这几件事不涉及配置文件,是写文章过程里养成的习惯,但对 SEO 的影响不比前面那些技术设置小。
给图片写清楚 alt 文字
Markdown 插入图片的语法是 ,中间这段"描述文字"就是 alt 文字。很多人图省事直接留空,或者写成 image1 这种没有意义的占位词。
alt 文字的作用:一是让图片有机会被 Google 图片搜索收录,二是给视觉障碍读者用的屏幕阅读器提供描述,这是网页无障碍访问的基本要求。写的时候按图片实际内容描述就行,比如"Cloudflare Pages 构建配置页面截图",不用堆关键词。
正文标题别跳级
文章标题(Front Matter 里的 title)本身在页面上渲染出来就是 H1,正文里不要再手动打出一个一级标题。正文小标题统一用二级标题(##),如果某个步骤下面还要细分,再往下用三级标题(###),不要因为想要字号大就跳着用。
本地预览时按 F12 打开浏览器开发者工具,在 Elements 面板里搜一下 <h1>,一篇文章正常情况下应该只有一个。
记得加内链
每篇文章末尾的"系列导航"只覆盖了同系列的前后篇,但写到正文中间提到相关内容时——比如这篇提到了 eSIM、那篇刚好写过 eSIM 测评——应该直接加个链接过去。这个不需要改任何配置,纯粹是写作时养成的习惯:写完一篇文章发布前,回头扫一眼正文,看看有没有提到过自己写过的其他主题,顺手加上链接。
内链做得好,读者会在站内多停留几篇文章,搜索引擎也更容易理解你网站不同文章之间的关联。
几个用得上再处理的技术点
下面这几件事现在用不上,但提前知道,到时候不会手忙脚乱。
网站速度
打开 PageSpeed Insights,输入博客首页或者某篇文章的网址,它会给出评分和具体建议(图片太大、字体加载慢之类)。
网页加载慢的主要原因,通常是图片——截图、配图如果不压缩直接传上去,文件可能几 MB 起步。发布文章最好压缩一下,这里建议将图片转为webp格式,这个很多工具都能做到,比如photoshop工具,免费看图工具IrfanView,压缩后图片能控制在几百 KB 以内,比改任何配置都管用。
自定义404页面
Stack 主题自带一份默认的404页面,效果基本够用,不是必须改。如果想自定义文字内容,可以试着在 content/ 目录下新建 404.md;如果改了不生效,说明主题用的是固定模板,需要把主题的 layouts/404.html 复制一份到自己站点的 layouts/ 目录里再改——跟之前改侧边栏小部件遇到的情况是同一个套路。
优先级不高,有空再做。
以后改 URL,别忘了做重定向
哪天想给某篇文章换个 url(比如发现关键词不够精准),如果只是改了 Front Matter 里的 url 字段直接发布,旧链接会直接变成404——之前 Google 收录的排名、外部平台分享出去的链接,全部断掉。
正确做法是同时设置一个跳转:在 myblog/static/ 目录下新建一个叫 _redirects 的文件(没有后缀名),格式是"旧路径 新路径 状态码",每条规则一行:
|
|
比如把 /old-slug 改成了 /new-slug:
|
|
这个文件放在 static/ 目录下,Hugo 构建时会原样复制到网站根目录,Cloudflare Pages 会自动识别并按这个规则跳转,不需要额外配置。现在用不上,但等真到了要改 URL 那天,记得来翻这一段。
常见报错与解决
报错现象:robots.txt 写完之后,Google Search Console 的索引报告显示大量页面被屏蔽
原因:八成是 User-agent: * 下面的规则写反了,把 Allow: / 写成了 Disallow: /。
解决步骤:打开线上的 /robots.txt,逐行检查最顶部那组通用规则,确认是 Allow: /;改完重新推送,等 Cloudflare 构建完成后在 Search Console 里用"网址检查"工具重新测一遍这个页面。
报错现象:加完结构化数据那段代码,网站直接构建失败
原因:通常是 JSON 格式本身写错了(比如多打了一个逗号、少了一个引号),或者代码片段放的位置不对。
解决步骤:检查路径是不是 layouts/partials/head/custom.html(注意是 partials 不是 _partials,Stack 主题内部用 _partials,站点自定义文件放 partials);检查大括号、逗号是不是一一对应,确认每个文字字段都套了 jsonify 而不是自己手写引号。
报错现象:_redirects 文件加了规则,但访问旧链接没有跳转,还是显示404
原因:Cloudflare 对 _redirects 里的空格数量很敏感,规则的几部分之间必须用空格或 Tab 分隔,多余的空格可能导致规则被忽略。
解决步骤:打开 Cloudflare Pages 后台对应这次部署的构建日志,看有没有提示某条规则被忽略;本地编辑时用一个 Tab 键代替手动敲多个空格,比较不容易出这种问题。
这篇做完,你拥有了什么
- 不想被拿去训练 AI 模型的内容,可以通过 robots.txt 挡住对应爬虫,且不影响搜索引擎正常收录
- 文章在 Google 搜索结果里有机会多显示发布日期等额外信息
- 图片 alt、标题结构、内链这些容易被忽略的写作细节捋清楚了
- 网站速度、自定义404、URL 重定向这些以后用得上的技术点,提前心里有数了
这些大多是一次性配置或者写作习惯,做熟了之后基本不用再操心。
下一篇会回到博客本身的功能上,聊聊评论系统、多语言配置和站内搜索优化这几块。
完整 Front Matter 见文章开头,完整访问地址: https://smallstep.one/hugo-seo-advanced/
系列导航
- 上一篇:中级04——流量与变现基础
- 下一篇:中级06-接入评论系统
- 返回系列目录:Hugo 建站指南