VitePress 生成标准 HTML,但不可直接修改 public/index.html;其页面由 Markdown + Vue 动态生成,自定义 HTML 应通过 config.ts 的 head 配置或 Vue 组件实现,以保障热更新、导航、SEO 等功能正常。

HTML 与 VitePress 并非并列关系,而是“宿主”与“生成器”的关系——VitePress 构建时会输出标准 HTML,但你不能、也不该直接在 VitePress 项目里手写 index.html 去控制页面结构。 它的 HTML 是由 Vue 渲染逻辑 + Markdown 编译器 + Vite 预渲染流程共同生成的。强行干预底层 HTML,大概率破坏热更新、导航跳转、搜索索引或 SSR 兼容性。
为什么不能直接改 public/index.html?
VitePress 不像传统 Vite 应用那样依赖 public/index.html 作为入口模板。它的页面是按路由动态生成的:每个 .md 文件对应一个 HTML 页面,由 vitepress build 时通过 Vue SFC 编译 + 静态预渲染产出。你放进 public/ 的 HTML 文件不会被自动挂载到文档路由中,也不会参与侧边栏、搜索、i18n 等核心能力。
- 改了
public/index.html,开发时看不到效果(VitePress dev 模式不读它) - 构建后它会被原样复制到输出目录,但和文档页面完全隔离,无法共享状态或样式上下文
- 想加全局
<script></script>或<meta>,正确位置是.vitepress/config.ts的head配置项
如何安全注入自定义 HTML 片段?
真正需要插入 HTML(比如统计脚本、第三方 SDK、SEO meta),必须走 VitePress 官方支持的配置路径:
- 在
.vitepress/config.ts中使用head数组:head: [['script', { src: 'https://example.com/analytics.js', async: true }]] - 若需条件注入(如仅生产环境),配合
process.env.NODE_ENV === 'production'判断,但注意 config.ts 运行在 Node 环境,不是浏览器 - 要插入内联 JS 或复杂逻辑,封装成 Vue 组件(如
Analytics.vue),在Layout.vue或App.vue中 import 并使用
如何让自定义 HTML 与文档内容联动?
比如想在某个组件文档页底部加“Try it in Playground”按钮,且按钮行为依赖当前组件名——这必须靠 Vue 能力,而非静态 HTML:
- 不要写死
<button onclick="run('Button')"></button> - 改用 Markdown 中的 Vue 组件:
<playgroundbutton :component-name="$page.title"></playgroundbutton> - 组件内部可通过
useData()获取当前页面元数据,包括$page.title、$page.relativePath等 - 这样既保持响应式,又避免硬编码路径或名称,还能复用、测试、类型校验
最容易被忽略的是:VitePress 的 HTML 输出是“结果”,不是“输入”。所有定制必须落在配置层(config.ts)、主题层(theme/ 目录)、或内容层(Markdown + Vue 组件),而不是去碰构建产物或 public 模板。否则,一次升级、一个插件更新,就可能让手动写的 HTML 失效或冲突。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











