必须放在里,因HTML解析器在构建DOM前就提取其内容用于标签页、收藏夹和SEO;写在中会被部分浏览器忽略或错位,导致标题不显示。

浏览器标签页显示的标题,只认 里的第一个 <title></title> 标签;写错位置、重复写、用 JS 改 DOM 节点,全都不生效。
为什么 <title></title> 必须放在 里
HTML 解析器在构建 DOM 前就提取 <title></title> 内容用于标签页、收藏夹和搜索引擎摘要。它不是“渲染后才起作用”的元素,而是解析阶段就锁定的元信息。写在 里时,Chrome 可能自动挪进 ,但爬虫、旧版 Safari WebView、微信内置浏览器直接忽略——你看到标签页显示 index.html 或“无标题”,就是这个原因。
常见错误包括:
-
<title>首页</title>被模板引擎(如 EJS 的)插到了开头 - 手写 HTML 漏了
标签,<title></title>直接跟在后面 - Vue/React 项目开了 SSR,但服务端没注入真实标题,首屏 HTML 里
<title></title>是空的或默认值
动态改标题只能用 document.title,别碰 DOM
单页应用路由切换时,很多人写 document.querySelector('title').textContent = '新标题',这行代码确实能改 DOM 节点,但浏览器标签页文字完全不变——因为规范明确要求:只有赋值 document.title 才触发标题更新逻辑。
注意几个硬限制:
- IE6–8 对中文支持差,必须确保页面有
<meta charset="utf-8">且与文件实际编码一致 - 修改后不触发任何事件,无法用
addEventListener监听变化 - 微信/QQ 分享卡片取的是初始 HTML 中的
<title></title>,JS 后改的只影响当前标签页 - 不要在
setTimeout里延迟设置,应绑定到框架的路由就绪钩子(如 Vue Router 的afterEach、React Router 的useEffect+location.key)
构建工具会悄悄覆盖你写的 <title></title>
Vite 的 vite-plugin-html、Webpack 的 html-webpack-plugin 默认通过配置项注入标题,比如 title: '我的网站'。这时你源码里写的 <title>首页</title> 看着正常,构建后生成的 index.html 里早就被替换成插件生成的内容。
排查方法很简单:
- 别看源码,直接打开 dist 目录下的
index.html,搜索<title></title> - 检查插件配置是否启用了
templateParameters或inject: true - 需要自定义时,优先用插件提供的变量注入(如
<title></title>),而不是硬写静态文本
<title></title> 内容的长度和字符陷阱
搜索引擎通常只展示前 50–60 字符,移动端标签栏更窄——12 个汉字就可能被截断。更危险的是未转义字符:
-
&必须写成&,否则会被当成实体开头,导致标题截断甚至 HTML 解析失败 和 <code>>必须写成和 <code>>,否则破坏 HTML 结构- 中文、emoji、©、— 可以直接写,但全角空格、BOM 字符、零宽空格会导致解析异常
- 禁止出现
<script></script>、{{ title }}、onclick=等任何非纯文本内容
最常被忽略的一点:<title></title> 不只是展示字段,它参与页面唯一性判定、history.state 关联、PWA 安装横幅文案生成——一旦初始为空或错误,后续补救成本远高于一开始就写对。


















