1. 为什么头部元信息值得单独写一篇避坑指南
做前端这些年,我改过的页面没有一千也有八百。有个现象特别有意思:很多人写HTML,<body>里的东西精雕细琢,CSS调了又调,JS逻辑捋了又捋,但<head>里那几行<meta>,基本靠复制粘贴,从上一个项目原封不动搬过来。等到页面分享到社交平台没缩略图、移动端打开字小得要用放大镜、搜索引擎收录的标题是一串乱码,才开始回头翻<head>,一查一个准。
<head>里的元信息,说白了就是给浏览器、搜索引擎、社交平台这些“非人类读者”看的说明书。用户看不到它,但它决定了用户怎么看到你的页面。charset决定中文会不会变乱码,viewport决定手机上排版是正常还是稀碎,description和title决定搜索结果里那两行字长什么样,Open Graph 系列决定链接分享到聊天窗口时是光秃秃一条还是带图带摘要的卡片。
这篇内容适合所有写HTML的人看——不管你是刚学<html lang="zh-cn">怎么写的新手,还是做了几年项目、觉得<head>早就烂熟于心的老手。我见过太多“老手”在viewport上栽跟头,也见过不少项目因为一个charset的位置问题导致整页乱码。下面我按“整体设计思路 → 核心标签逐个拆 → 完整实操流程 → 常见问题排查”的顺序,把<head>里那些坑一个个填平。
2. 头部元信息的整体设计思路与取舍逻辑
2.1 元信息的三类“读者”与对应策略
写<head>之前得先想清楚:这些标签是写给谁看的。我习惯把它们分成三类读者,每类读者的诉求完全不同,标签的写法和优先级也不一样。
第一类是浏览器。浏览器关心的是:这页用什么字符集解码?用什么渲染模式?移动端按什么宽度布局?对应的是charset、X-UA-Compatible(现在基本可以不管了)、viewport这几个。这类标签的特点是“错了就出硬伤”——乱码、布局错乱、缩放异常,用户一眼就能看出来。
第二类是搜索引擎。搜索引擎关心的是:这页标题是什么?内容摘要是什么?能不能被收录?能不能被跟踪?对应的是title、description、keywords(现在权重极低)、robots、canonical。这类标签错了不会立刻出问题,但会影响长期的流量表现,属于“慢性病”。
第三类是社交平台与外部应用。当你的链接被分享到聊天工具、社交动态、内容聚合平台时,对方会去抓取 Open Graph 或 Twitter Card 标签来生成预览卡片。对应的是og:title、og:description、og:image、og:url这一套。这类标签错了,分享出去的链接就是一条干巴巴的文字,点击率直接打对折。
把这三类读者想清楚,<head>里该放什么、按什么顺序放,心里就有谱了。我的习惯是:charset 放最前面,viewport 紧随其后,然后是 title,再是 description 和 OG 系列,最后是 canonical 和 robots 这类辅助标签。这个顺序不是随便排的,后面讲 charset 的时候会解释为什么它必须尽量靠前。
2.2 从“能跑就行”到“每个标签都有理由”
很多项目的<head>是从模板或者别的项目抄来的,抄的时候也没想过每个标签是干嘛的。我早期也这样,直到有一次排查一个线上问题:某页面在部分安卓机上字体异常小,查了半天CSS没找到原因,最后发现是viewport写成了width=device-width, initial-scale=0.5——不知道从哪个项目抄来的,那个0.5直接把整个页面缩了一半。
从那以后我养成了一个习惯:<head>里每一个标签,我都要能说出它为什么在那儿。说不出来的,要么查清楚,要么删掉。这个习惯帮我避掉了不少坑。比如keywords这个标签,早年做SEO的人会塞一大堆关键词进去,但现在主流搜索引擎基本不参考它了,塞多了反而可能被判定为堆砌。我现在除非有特殊需求,否则不写keywords。
再比如X-UA-Compatible,这是当年为了兼容旧版IE浏览器用的,现在IE已经退出历史舞台,这个标签留着除了增加几字节体积,没有任何作用。类似的还有一堆“历史遗留标签”,该清理就清理,<head>越干净,出问题的概率越小。
2.3 元信息的“最小可用集”与“完整集”
根据项目类型不同,<head>的配置可以分成两档。
最小可用集适合内部工具、demo页面、临时活动页这类不需要被搜索引擎收录、不需要社交分享的场景:
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>页面标题</title> </head> <body> ... </body> </html>完整集适合官网、博客、电商详情页、内容页这类需要SEO和社交传播的场景,在最小集基础上加上 description、OG 系列、canonical、favicon 等:
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>页面标题 - 站点名称</title> <meta name="description" content="页面摘要,控制在80-120字"> <link rel="canonical" href="https://example.com/page"> <meta property="og:type" content="website"> <meta property="og:title" content="分享标题"> <meta property="og:description" content="分享摘要"> <meta property="og:image" content="https://example.com/share.png"> <meta property="og:url" content="https://example.com/page"> <link rel="icon" href="/favicon.ico"> </head> <body> ... </body> </html>判断用哪一档,就看这个页面“要不要被外人看到”。内部工具没人分享、不需要搜索流量,最小集就够了,写多了是负担。对外页面,完整集该上就上,省这几行代码省不出什么,但缺了OG图,分享出去的链接点击率差一截,这个损失是实打实的。
3. 核心元信息标签逐个拆解与实操要点
3.1 charset:为什么它必须放在最前面
<meta charset="UTF-8">这行代码,几乎所有HTML模板里都有,但它的位置经常被忽略。我见过不少项目把它放在<title>后面,甚至放在一堆OG标签后面。平时可能不出问题,但一旦服务器返回的HTTP头里没有声明字符集,浏览器就会开始“猜”编码,猜错了就是满屏乱码。
浏览器解析HTML是从上往下逐字节读的。当它读到<meta charset>时,才知道“哦,这页是UTF-8”,然后切换解码方式。如果这行出现在<title>之后,那<title>里的中文就可能已经被用错误的编码解析了,结果就是标签页上显示一串问号或者方块。
注意:
<meta charset>应该出现在<head>的第一个位置,在<title>和任何其他标签之前。规范建议它出现在前1024字节内,越靠前越安全。
实操上,我的习惯是<head>开标签之后第一行就写 charset,不给自己留犯错的机会。另外,charset的值统一用UTF-8,不要用gb2312或gbk。UTF-8 是现在的事实标准,能覆盖所有中文字符和特殊符号,gb系列在遇到生僻字或者emoji时会出问题。
还有一个容易忽略的点:文件本身的保存编码要和 charset 声明一致。我遇到过有人HTML文件用GBK保存,但<meta charset="UTF-8">,本地打开正常(因为编辑器自动识别了),部署到服务器就乱码。排查这种问题,先看文件编码,再看meta声明,两边对齐才行。
3.2 viewport:移动端排版的命门
viewport这个标签,是移动端适配的起点。没有它,手机浏览器会默认按桌面宽度(通常是980px)渲染页面,然后整体缩小,结果就是字小得看不清,用户得双指放大才能阅读。
标准写法是:
<meta name="viewport" content="width=device-width, initial-scale=1.0">width=device-width让页面宽度等于设备屏幕宽度,initial-scale=1.0让初始缩放比例为1,不放大也不缩小。这两个参数配合,页面在手机上就是正常大小。
但这里有几个坑:
坑一:initial-scale写成0.5或其他值。有些老项目为了让页面“看起来能放下更多内容”,把初始缩放设成0.5,结果就是所有文字和元素都缩小一半,用户得手动放大。这个值除非有特殊设计需求,否则就写1.0。
坑二:加了maximum-scale=1.0或user-scalable=no。这两个参数会禁止用户缩放页面。早年有些移动端项目为了防止用户放大后布局错乱,会加上这两个。但现在从可访问性角度,禁止缩放对视力不好的用户很不友好,主流做法是不加这两个参数,让用户自由缩放。
坑三:viewport和CSS媒体查询配合不当。有些项目写了viewport,但CSS里用的是固定像素宽度,比如width: 1200px,结果在手机上还是横向滚动。viewport只是设定了视口宽度,具体布局还得靠响应式CSS来配合,两者缺一不可。
实操心得:调试移动端布局时,我会在浏览器开发者工具里切换到手机模拟模式,然后检查
document.documentElement.clientWidth是否等于屏幕宽度。如果不等,说明 viewport 配置有问题。
3.3 title:搜索结果里的第一行字
<title>是<head>里唯一一个用户能直接看到的标签——它显示在浏览器标签页上,也是搜索引擎结果里那行蓝色的可点击文字。它的重要性怎么强调都不过分。
写title有几个原则:
长度控制在30个字以内。搜索引擎结果里,标题超过一定长度会被截断,一般PC端显示约30个汉字,移动端更短。重要的信息放前面,站点名称放后面,用短横线或竖线分隔。比如“HTML头部元信息避坑指南 - 前端笔记”就比“前端笔记 - HTML头部元信息避坑指南”更好,因为用户搜索时更可能搜“HTML头部元信息”而不是“前端笔记”。
每个页面用不同的 title。我见过整站所有页面 title 都一样的,这种在搜索引擎看来就是重复内容,收录效果很差。列表页、详情页、关于页,title 都应该有区分。
不要堆砌关键词。早年SEO流行在 title 里塞一堆关键词,比如“HTML教程,HTML入门,HTML学习,HTML基础”,现在这么做基本没有正面效果,反而可能被判定为作弊。title 写清楚这页是什么就行。
特殊字符要转义。如果 title 里需要用到<、>、&这些字符,要写成<、>、&,否则可能破坏HTML结构。
3.4 description:决定点击率的那段摘要
<meta name="description">不直接影响排名,但它影响搜索结果里标题下面那段摘要文字。写得好,用户更可能点进来;写得差或者不写,搜索引擎会自己从页面内容里抓一段,抓出来的可能是不相干的导航文字或者版权声明。
写 description 的要点:
长度控制在80到120个汉字。太短信息量不够,太长会被截断。PC端一般显示两行,移动端显示三行左右。
每页不同,概括页面核心内容。不要所有页面用同一段 description,那样等于没写。
自然融入关键词,但不要堆砌。description 里出现用户可能搜索的词,搜索引擎会加粗显示,提升点击率。但硬塞一堆关键词读起来不通顺,反而降低可信度。
写成一句通顺的话,不是关键词列表。“本文介绍HTML头部元信息,包括charset、viewport、SEO标签的写法和避坑技巧”就比“HTML,元信息,charset,viewport,SEO,避坑”要好得多。
3.5 Open Graph:分享卡片的门面
Open Graph 协议最初由社交平台提出,现在已经被主流社交工具和内容平台广泛支持。当你的链接被分享出去时,对方会抓取og:开头的标签来生成预览卡片。
核心的OG标签有四个:
| 标签 | 作用 | 示例 |
|---|---|---|
og:title | 卡片标题 | <meta property="og:title" content="HTML头部元信息避坑指南"> |
og:description | 卡片摘要 | <meta property="og:description" content="拆解charset、viewport、SEO标签的常见坑"> |
og:image | 卡片配图 | <meta property="og:image" content="https://example.com/cover.png"> |
og:url | 页面规范链接 | <meta property="og:url" content="https://example.com/article"> |
og:image是最容易出问题的一个。几个注意点:
图片必须是绝对URL。写/cover.png不行,必须是https://example.com/cover.png,因为抓取方不知道你的域名是什么。
图片尺寸建议 1200x630 像素。这是主流平台推荐的尺寸,比例接近1.91:1。太小会显示模糊,太大加载慢。小于 200x200 的图片很多平台直接不显示。
图片要能被公开访问。如果图片放在需要登录才能访问的路径下,抓取方拿不到图,卡片就没图。
og:url 用 canonical 链接。如果页面有多个URL可以访问(比如带参数和不带参数的),og:url 应该指向规范的那个,避免分享数据分散。
除了OG,还有一套 Twitter Card 标签,写法类似,但现在主流平台基本都兼容OG,除非有特别需求,否则OG一套就够了。
3.6 canonical 与 robots:收录控制的开关
<link rel="canonical" href="...">用来告诉搜索引擎“这个页面的规范版本是哪个URL”。当同一内容有多个URL可访问时(比如带分页参数、带跟踪参数、http和https都能访问),canonical 可以避免搜索引擎把它们当成不同页面,分散权重。
<meta name="robots" content="...">控制搜索引擎对本页的抓取和收录行为。常用值:
index, follow:默认值,收录本页,跟踪本页链接noindex, follow:不收录本页,但跟踪链接noindex, nofollow:不收录,不跟踪
内部搜索结果页、用户个人中心页、测试页面,通常用noindex避免被收录。但要注意,noindex只是建议,不是强制,搜索引擎不一定会遵守,但主流搜索引擎都会尊重这个标签。
注意:robots 标签和 robots.txt 文件是两回事。robots.txt 控制整个站点的抓取范围,robots meta 控制单个页面的收录行为。两者可以配合使用。
4. 完整实操流程:从零写一个规范的 head
4.1 第一步:确定页面类型和需求
动手写之前,先问自己几个问题:
- 这个页面需要被搜索引擎收录吗?——决定要不要写 description、canonical、robots
- 这个页面会被分享到社交平台吗?——决定要不要写 OG 系列
- 这个页面主要在什么设备上访问?——决定 viewport 和响应式策略
- 这个页面有多个URL版本吗?——决定 canonical 怎么写
这几个问题的答案,直接决定了<head>里放哪些标签。比如一个内部管理后台,答案全是“不需要”,那最小可用集就够了。一个电商商品详情页,答案全是“需要”,那就得写完整集。
4.2 第二步:按顺序搭建 head 骨架
我习惯按这个顺序写:
<!DOCTYPE html> <html lang="zh-CN"> <head> <!-- 1. 字符集,必须最前 --> <meta charset="UTF-8"> <!-- 2. viewport,移动端适配 --> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- 3. 标题 --> <title>页面标题 - 站点名</title> <!-- 4. 描述 --> <meta name="description" content="页面摘要"> <!-- 5. 规范链接 --> <link rel="canonical" href="https://example.com/page"> <!-- 6. 收录控制(按需) --> <meta name="robots" content="index, follow"> <!-- 7. Open Graph --> <meta property="og:type" content="website"> <meta property="og:title" content="分享标题"> <meta property="og:description" content="分享摘要"> <meta property="og:image" content="https://example.com/cover.png"> <meta property="og:url" content="https://example.com/page"> <!-- 8. 图标 --> <link rel="icon" href="/favicon.ico"> <!-- 9. 样式表 --> <link rel="stylesheet" href="/style.css"> </head>这个顺序的逻辑是:先处理“错了就出硬伤”的标签(charset、viewport),再处理“影响长期表现”的标签(title、description、canonical、OG),最后是资源引用(icon、stylesheet)。样式表放最后是因为它可能阻塞渲染,放后面让前面的元信息先被解析。
4.3 第三步:填充内容并检查
骨架搭好后,逐个填充内容。这里以一篇博客文章页为例:
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>HTML头部元信息避坑指南 - 前端笔记</title> <meta name="description" content="拆解charset、viewport、title、description、Open Graph等头部元信息的常见坑和正确写法,附完整实操代码。"> <link rel="canonical" href="https://example.com/posts/html-head-meta-guide"> <meta name="robots" content="index, follow"> <meta property="og:type" content="article"> <meta property="og:title" content="HTML头部元信息避坑指南"> <meta property="og:description" content="拆解charset、viewport、SEO标签的常见坑和正确写法。"> <meta property="og:image" content="https://example.com/images/html-head-cover.png"> <meta property="og:url" content="https://example.com/posts/html-head-meta-guide"> <link rel="icon" href="/favicon.ico"> <link rel="stylesheet" href="/css/main.css"> </head> <body> ... </body> </html>填充完之后,我会做几个检查:
- charset 是不是在 head 第一行?
- viewport 的 initial-scale 是不是 1.0?
- title 有没有超过30个字?有没有包含站点名?
- description 有没有超过120个字?读起来通顺吗?
- og:image 是不是绝对URL?能不能公开访问?
- canonical 是不是指向规范URL?
这几个检查做完,<head>基本就没大问题了。
4.4 第四步:验证与调试
写完不是终点,还得验证。我常用的验证手段:
浏览器开发者工具。打开页面,在 Elements 面板里看<head>的解析结果,确认没有标签被错误嵌套或者被浏览器自动修正。
移动端模拟。在开发者工具里切换到手机模式,检查页面宽度是否等于屏幕宽度,文字大小是否正常,有没有横向滚动。
社交分享调试。大部分社交平台都有分享调试工具,输入URL可以预览卡片效果。如果没有现成工具,可以手动构造一个分享链接发给自己,看预览效果。
搜索引擎收录检查。页面部署后,用site:指令在搜索引擎里查一下,看是否被收录,标题和描述显示是否正常。
5. 常见问题与排查技巧实录
5.1 中文乱码:从文件编码到HTTP头逐层排查
中文乱码是最常见的问题,排查思路是从“文件本身”到“传输过程”到“解析声明”逐层检查。
第一层:文件保存编码。用编辑器打开HTML文件,查看文件编码设置。VS Code 右下角会显示当前文件编码,如果不是 UTF-8,改成 UTF-8 保存。注意有些编辑器默认用系统编码(Windows中文版可能是GBK),新建文件时要手动选 UTF-8。
第二层:meta charset 声明。确认<meta charset="UTF-8">存在且在最前面。如果这行写的是gb2312但文件是 UTF-8 保存的,也会乱码。
第三层:服务器HTTP头。有些服务器会在HTTP响应头里声明Content-Type: text/html; charset=gbk,这个优先级高于 meta 标签。如果服务器头声明了GBK但页面是UTF-8,浏览器会按GBK解析,结果乱码。这种情况需要改服务器配置,或者在服务器头里也声明UTF-8。
排查顺序:先看文件编码,再看meta,最后看HTTP头。三层都对齐UTF-8,乱码问题基本就解决了。
5.2 移动端布局错乱:viewport 与 CSS 的配合问题
移动端布局错乱,很多时候不是 viewport 一个人的锅,而是 viewport 和 CSS 配合出了问题。
症状一:页面整体缩小,字很小。检查 viewport 的initial-scale是不是被设成了小于1的值。改成1.0。
症状二:页面横向滚动。检查CSS里有没有固定宽度超过屏幕宽度的元素。比如width: 1200px的容器,在375px宽的手机上就会横向滚动。改成max-width: 1200px; width: 100%。
症状三:字体大小异常。有些安卓浏览器会自动调整字体大小(Font Boosting),导致设置了font-size: 14px的文字显示成18px。可以在CSS里加-webkit-text-size-adjust: 100%来禁止自动调整。
症状四:点击区域太小。移动端手指点击精度不如鼠标,按钮和链接的点击区域建议不小于44x44像素。这个不是 viewport 的问题,是交互设计的问题,但经常和移动端布局问题一起出现。
5.3 社交分享无图无摘要:OG标签的常见错误
分享出去没图没摘要,按这个清单排查:
| 问题现象 | 可能原因 | 解决方法 |
|---|---|---|
| 完全没卡片,只有链接 | OG标签缺失或写错 | 检查 og:title、og:description、og:image 是否存在 |
| 有卡片但没图 | og:image 是相对路径 | 改成绝对URL |
| 有卡片但图裂了 | og:image 无法公开访问 | 确认图片URL在无登录状态下能打开 |
| 图很小很模糊 | 图片尺寸太小 | 换成 1200x630 像素的图 |
| 标题摘要不对 | 抓取了页面其他内容 | 检查 og:title 和 og:description 是否写对 |
| 改了标签但分享还是旧的 | 平台缓存 | 用平台的调试工具刷新缓存,或换个URL参数测试 |
实操心得:OG标签的调试最麻烦的是缓存。平台抓取过一次后会缓存一段时间,改了标签不会立刻生效。测试时可以在URL后面加个随机参数(如
?v=123)来绕过缓存,确认标签写对了再发布正式URL。
5.4 title 和 description 被搜索引擎改写
有时候你写了 title 和 description,但搜索引擎结果显示的不是你写的内容。这通常有几个原因:
title 太长被截断或改写。搜索引擎会根据用户查询词,从 title 里截取相关部分显示,或者用页面里的其他文字替换。控制 title 长度,把核心信息放前面,可以减少被改写的概率。
description 被认为质量不高。如果 description 是关键词堆砌、或者和页面内容不符,搜索引擎会从页面正文里抓一段更相关的文字来显示。写一段通顺、概括页面内容的 description,被采用的概率更高。
页面内容与 title/description 不符。如果 title 写的是“HTML教程”但页面内容是“CSS教程”,搜索引擎会认为 title 误导用户,从而改写。保持三者一致。
5.5 多个页面共用同一套 head 的维护问题
项目大了之后,几十个页面共用同一套<head>模板,改一个标签要改几十个文件,很容易漏。我的做法是:
用模板引擎或构建工具。如果项目用了模板引擎(如 Jinja2、Handlebars)或者构建工具(如 Webpack、Vite),把<head>抽成一个公共模板,各页面只传 title、description、og:image 这几个变量。这样改公共部分只改一处。
用服务端渲染动态生成。如果是服务端渲染的页面,可以在服务端根据页面数据动态生成<head>。比如博客文章页,title 用文章标题,description 用文章摘要,og:image 用文章封面图,都是自动填充的。
定期用脚本检查。写个简单的脚本,爬取站点所有页面,检查每个页面的<head>是否包含必需的标签,title 和 description 是否为空,og:image 是否可访问。这种检查放在CI流程里,每次部署前跑一遍,能提前发现很多问题。
6. 几个容易被忽略的细节与个人经验
6.1 lang 属性的正确写法
<html lang="zh-CN">这个属性,很多人随手写lang="zh"或者lang="cn"。zh是中文的ISO 639代码,CN是中国地区的ISO 3166代码,合起来zh-CN表示“中文-中国大陆”。写cn是错的,因为cn不是语言代码。写zh虽然不算错,但不够精确,搜索引擎和屏幕阅读器可能无法准确判断地区变体。
对于中文页面,推荐用zh-CN。如果是繁体中文,用zh-TW或zh-HK。这个属性影响搜索引擎的地区定向,也影响屏幕阅读器的发音,值得写对。
6.2 favicon 的兼容性写法
<link rel="icon" href="/favicon.ico">是最基本的写法,但不同设备和平台对图标的要求不一样。完整的写法会包含多个尺寸:
<link rel="icon" type="image/x-icon" href="/favicon.ico"> <link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png"> <link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png"> <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">apple-touch-icon是给iOS设备添加到主屏幕时用的,尺寸建议180x180。如果不写这个,iOS会用页面截图作为图标,效果通常不好。
6.3 预加载与预连接:提升加载速度的 head 标签
除了元信息,<head>里还可以放一些资源提示标签,用来优化加载速度:
<link rel="preconnect" href="https://fonts.example.com"> <link rel="dns-prefetch" href="https://cdn.example.com"> <link rel="preload" href="/fonts/main.woff2" as="font" type="font/woff2" crossorigin>preconnect提前建立到第三方域名的连接,dns-prefetch提前解析DNS,preload提前加载关键资源。这几个标签用好了能明显提升首屏速度,但不要滥用,每个标签都会占用浏览器资源,只对关键资源用。
6.4 我踩过的一个真实坑:charset 位置导致的白屏
最后分享一个我早期踩过的坑。有一次做一个活动页,<head>里先写了一堆OG标签和样式表,<meta charset>放在了比较靠后的位置。本地测试一切正常,部署到服务器后,部分用户反馈页面白屏。
排查了半天,最后发现是服务器在某些情况下没有在HTTP头里声明字符集,浏览器只能靠<meta charset>来判断。但因为 charset 位置太靠后,浏览器在读到它之前已经用默认编码解析了前面的内容,导致解析出错,页面渲染失败。
把<meta charset="UTF-8">移到<head>第一行之后,问题解决。这个坑让我彻底记住了:charset 必须最前,没有例外。
6.5 关于 keywords 标签的现状
<meta name="keywords">这个标签,早年是SEO的标配,现在主流搜索引擎基本不参考它了。我现在的做法是:除非有明确的内部搜索需求(比如站内搜索需要用到),否则不写。写了不仅没用,还可能因为关键词堆砌被扣分。
如果确实要写,控制在5到10个词,用英文逗号分隔,不要重复,不要塞无关词。但说实话,我最近几年做的项目,<head>里已经基本看不到这个标签了。
6.6 动态页面的 head 处理
对于单页应用(SPA),<head>的处理比较特殊。因为SPA通常只有一个HTML入口,路由切换时<head>不会自动更新。这时候需要用JS动态修改 title 和 meta 标签。
React 项目可以用react-helmet或react-helmet-async,Vue 项目可以用@vueuse/head或vue-meta。这些库的原理都差不多:在组件里声明当前页面需要的 title 和 meta,库负责在路由切换时更新<head>。
需要注意的是,SPA 的动态 meta 对搜索引擎来说可能抓不到,因为搜索引擎爬虫不一定执行JS。如果SEO很重要,建议用服务端渲染(SSR)或静态生成(SSG),让<head>在服务端就渲染好。
6.7 一个快速检查 head 是否规范的方法
最后分享一个我常用的快速检查方法。打开浏览器开发者工具,在 Console 里跑这段代码:
const head = document.head; const checks = { charset: !!head.querySelector('meta[charset]'), viewport: !!head.querySelector('meta[name="viewport"]'), title: !!head.querySelector('title')?.textContent, description: !!head.querySelector('meta[name="description"]')?.content, ogTitle: !!head.querySelector('meta[property="og:title"]')?.content, ogImage: !!head.querySelector('meta[property="og:image"]')?.content, canonical: !!head.querySelector('link[rel="canonical"]')?.href, }; console.table(checks);这段代码会输出一个表格,显示各个关键标签是否存在。false的项就是需要补的。这个方法适合快速排查,尤其是接手别人项目的时候,跑一下就知道<head>缺了什么。
这个检查脚本我放在书签里,随时点一下就能用。对于需要批量检查的场景,可以把它改成爬虫脚本,遍历站点所有页面,输出一份完整的检查报告。