输入关键词开始搜索

配置站点信息

4307 字 约 11 分钟

项目有两个配置入口,它们服务于不同层级:

文件职责什么时候修改
src/.vitepress/site.config.ts站点名称、作者、动态身份、导航、社交入口、分页、图标、Feed 和评论搭建自己的博客时需要修改
src/.vitepress/config.tsVitePress 路由、Markdown、侧栏、SEO、资源注入和构建钩子调整工程能力时才修改

日常配置优先集中在 site.config.ts。页面组件和构建逻辑会读取这里的数据,不应在组件中重复写作者名称、域名或社交账号。

配置单元测试只检查非空文本、有效地址、正整数、派生行为和本地资源是否存在,不固定站点名称、个人文案、账号、导航内容、数量取值或 Giscus ID。正常修改这些配置时无需同步改写测试期望;只有新增配置结构或改变配置规则时才需要更新测试。

环境变量 ​

域名和部署路径由环境变量注入,不建议硬编码到 site.config.ts。

变量必填用途示例值
SITE_URL生产构建必填站点完整来源地址,用于 canonical、Open Graph、sitemap、robots 和 Feedhttps://username.github.io
SITE_BASE否站点部署子路径;根站点使用 // 或 /blog/

SITE_URL 不包含末尾 /。SITE_BASE 应同时保留开头和结尾的 /;未设置或设置为 / 时表示部署在域名根路径。

本地开发不要求 SITE_URL。需要检查生产输出时,项目已提供固定占位域名的命令:

powershell
pnpm build:local
pnpm preview

GitHub Pages workflow 在 .github/workflows/deploy.yml 中声明:

yaml
env:
  SITE_URL: https://${{ github.repository_owner }}.github.io
  SITE_BASE: /

如果仓库发布到项目子路径,需要把 SITE_BASE 改成 /<repository>/,并保证 Pages 的实际访问路径与之相同。

站点信息 ​

siteConfig.site 控制全站公共信息和输出路径。

配置类型建议修改用途当前值示例
titlestring是VitePress 站点标题、页面标题后缀和首页标题Bean Blog
namestring是页头品牌名和 Web App Manifest 名称Bean Blog
descriptionstring是默认站点描述;页面未单独声明时用于 SEO 和 Feed记录工程实践、技术思考与持续学习。
keywordsstring[]是普通页面的默认 SEO 关键词["VitePress", "前端开发"]
urlstring否从 SITE_URL 读取并移除末尾 /https://username.github.io
basestring否从 SITE_BASE 或 Vite BASE_URL 读取并规范为首尾带 / 的路径/
localestring按需Open Graph 地区代码zh_CN
languagestring按需HTML、VitePress 和 Feed 的语言代码zh-CN
featuredPostsLimitnumber按需首页“推荐阅读”最多展示的最新文章数量5
postsPerPagenumber按需文章列表每页显示的文章数量3
logostring是页头品牌 Logo 的公开路径/logo.svg
faviconobject是浏览器和设备图标路径,字段见下表见下表
manifeststring按需Web App Manifest 的公开路径/site.webmanifest
feedsobject按需RSS、Atom 和 JSON Feed 的输出路径见下表

图标配置 ​

Logo 与 favicon 文件保存在 src/public,配置值使用以 / 开头的公开路径。根目录的 bean-convex-concave-concept-v33.svg 是图标源文件,运行 pnpm generate:assets 会同步生成 logo.svg、三种 favicon 文件;构建时会自动拼接 SITE_BASE。

配置类型建议修改用途当前值
favicon.icostring是兼容性 favicon/favicon.ico
favicon.pngstring是PNG favicon/favicon.png
favicon.svgstring是SVG favicon/favicon.svg

Feed 配置 ​

这些路径同时用于静态文件生成、页面 <head> 声明和站内 RSS 链接。

配置类型建议修改用途当前值
feeds.rssstring按需RSS 2.0 主地址/rss.xml
feeds.rssAliasstring按需RSS 兼容别名/index.xml
feeds.atomstring按需Atom Feed 地址/atom.xml
feeds.jsonstring按需JSON Feed 地址/feed.json

作者信息 ​

siteConfig.author 用于首页、文章信息和 Feed 作者信息。

配置类型建议修改用途当前值示例
namestring是作者显示名称Bean
emailstring是Feed 等输出中的作者邮箱hello@example.com
biostring是首页作者简介一名持续学习的软件工程师。

动态页配置 ​

siteConfig.moment 集中控制 /moment 的个人区和滚动批次,不需要在每条动态中重复声明作者身份。

配置类型建议修改用途当前值示例
coversstring[]是个人区封面列表,进入页面时随机选择一张[/moments/cover.webp, ...]
displayNamestring按需动态作者名;省略或留空时回退到 author.nameBean
avatarstring按需动态头像;省略或留空时回退到 site.favicon.svg/favicon.svg
avatarsRecord<string, string>按需可按名称选择的头像库,省略时为空{ daily: "/moments/daily.webp" }
signaturestring按需个人签名;省略或留空时回退到 author.bio一名持续学习的软件工程师。
momentBatchSizenumber按需首批和后续每批动态数量,必须是正整数4

covers 至少提供一项,空路径会导致配置加载失败,重复路径会自动去重。每次进入 /moment 时页面随机选择一张,停留期间不会自行切换:

ts
covers: ["/moments/cover.webp", "/moments/cover-spring.webp", "/moments/cover-night.webp"],

moment.avatar 是顶部个人区和未指定头像的动态共用的默认头像。当前配置显式使用 avatar: favicon.svg,也可以独立设置为 avatar: "/moments/avatar.webp";省略或留空仍回退到站点图标。

需要发布动态时选择不同头像,可在同一配置中通过 avatars 为图片命名:

ts
avatar: favicon.svg,
avatars: {
  default: favicon.svg,
  daily: "/moments/daily.webp",
  travel: "https://images.example.com/travel.webp",
},

动态文件的 frontmatter 填写 avatar: daily 即可选择 avatars.daily。省略 avatar 时继续使用 moment.avatar,顶部个人区始终使用默认头像,不随单条选择变化。头像名称区分大小写,可以使用中文;名称和地址都会去除首尾空白,不能为空,规范化后的名称不能重复。未配置的名称会在构建期报告对应动态的 avatar 错误,frontmatter 中填写的是名称,不是图片地址。

本地封面和头像存放在 src/public,配置值使用以 / 开头的公开路径;也可使用完整 http/https 图片 URL。页面会为本地路径和动态图片统一拼接 SITE_BASE,远程 URL 保持原地址。完整写作格式见发布短动态。

导航配置 ​

siteConfig.navigation 是 NavItem[]。有 href 的项目是直接链接,有 children 的项目显示为下拉菜单;children 仍是 NavItem[],因此支持继续嵌套。

NavItem 字段类型必填用途
titlestring是导航显示文字
hrefstring否目标地址;内部地址以 / 开头,外部地址使用完整 HTTPS URL
childrenNavItem[]否子导航列表
ts
const navigation = [
  { title: "文章", href: "/blog" },
  { title: "动态", href: "/moment" },
  { title: "使用手册", href: "/blog/guide/getting-started" },
  {
    title: "浏览",
    children: [
      { title: "标签", href: "/tags" },
      { title: "归档", href: "/archives" },
    ],
  },
];

社交入口 ​

homeSocials 控制首页的文字社交入口。Header 只保留导航、搜索和主题切换,不显示社交图标。

SocialLink 字段类型必填用途
labelstring是首页显示文字和链接的无障碍名称
hrefstring是平台地址或站内 Feed 地址
ts
const homeSocials = [
  { label: "GitHub", href: "https://github.com/username" },
  { label: "RSS", href: "/rss.xml" },
];

没有有效地址的平台应直接从数组中移除,不保留空链接。

Giscus 评论 ​

博客使用 Giscus 将 GitHub Discussions 作为评论存储。站点不需要数据库或评论服务端;读者可以公开阅读评论,使用 GitHub 账号登录后参与讨论。

siteConfig.giscus 的类型是 GiscusConfig | null。不需要评论时保持 null;需要评论时,按照下面的流程准备 GitHub 仓库并获取配置参数。

准备 GitHub 仓库 ​

  1. 确保承载评论的 GitHub 仓库是公开仓库。评论仓库可以是博客源码仓库,也可以是单独创建的公开仓库。
  2. 打开仓库的 Settings,在 General > Features 中启用 Discussions。
  3. 打开 Giscus GitHub App,选择 Install 或 Configure,并授权它访问承载评论的仓库。只授权实际使用的仓库即可。
  4. 在仓库的 Discussions 页面确认至少有一个可用分类。推荐使用 Announcements,这样普通用户不能脱离文章随意创建新的主讨论。

如果 Giscus 配置页无法识别仓库,优先检查仓库是否公开、Discussions 是否启用,以及 Giscus App 是否已经获得该仓库的访问权限。

生成 Giscus 参数 ​

打开 Giscus 配置页,完成以下设置:

  1. 在“仓库”中填写 owner/repository。页面显示仓库满足条件后再继续。
  2. 在“页面 ↔️ Discussions 映射关系”中选择 pathname 对应的方案。本项目推荐 pathname,同一路径始终使用同一条 Discussion;文章 slug 改变后会被视为一篇新文章。
  3. 在“Discussion 分类”中选择前面准备的分类,通常使用 Announcements。
  4. 根据需要开启主贴反应,将评论框位置设为底部,并选择简体中文。
  5. 在页面底部找到生成的 <script>。不需要把这段脚本粘贴进 Vue 组件,只需把其中的 data-* 属性转换为 site.config.ts 的配置。
Giscus <script> 属性siteConfig.giscus 字段示例值
data-reporepoowner/repository
data-repo-idrepoIdR_...
data-categorycategoryAnnouncements
data-category-idcategoryIdDIC_...
data-mappingmappingpathname
data-reactions-enabledreactionsEnabled1
data-input-positioninputPositionbottom
data-langlangzh-CN

生成脚本中的 data-theme、data-strict、data-emit-metadata 和 data-loading 不需要写入站点配置:项目已经统一管理这些行为。

写入站点配置 ​

打开 src/.vitepress/site.config.ts,将默认的 giscus: null as GiscusConfig | null 替换为完整配置:

配置类型必填用途常用值
repo`${string}/${string}`是已启用 Discussions 的公开仓库owner/repository
repoIdstring是Giscus 提供的仓库 IDR_...
categorystring是Discussion 分类名称Announcements
categoryIdstring是Giscus 提供的分类 IDDIC_...
mapping"pathname" | "url" | "title" | "og:title"是页面与 Discussion 的映射方式pathname
reactionsEnabled"0" | "1"是是否启用主贴表态"1"
inputPosition"top" | "bottom"是评论输入框位置"bottom"
langstring是Giscus 界面语言zh-CN
ts
giscus: {
  repo: "owner/repository",
  repoId: "R_...",
  category: "Announcements",
  categoryId: "DIC_...",
  mapping: "pathname",
  reactionsEnabled: "1",
  inputPosition: "bottom",
  lang: "zh-CN",
} satisfies GiscusConfig | null,

不要根据仓库名称猜测 repoId 或 categoryId,这两个值必须从 Giscus 为目标仓库生成的脚本中复制。若以后更换评论仓库或 Discussion 分类,应回到配置页重新生成全部参数。

全部字段有效时,评论区会出现在文章正文下方;首页、文章列表、标签、归档和动态页不会加载评论。组件固定使用 strict="0"、emit-metadata="0" 和 loading="lazy",并在评论区接近视口时才加载 Giscus。评论主题会自动跟随 VitePress 的 appearance 状态,不需要在配置中重复声明。

验证评论功能 ​

  1. 执行 pnpm dev,打开任意文章详情页并滚动到正文底部。
  2. 确认评论框能够加载,登录 GitHub 后发送一条测试评论。
  3. 打开评论仓库的 Discussions,确认对应文章已经产生 Discussion。
  4. 执行 pnpm exec vitest run tests/unit/site-config.test.ts,检查配置字段和 ID 格式。

首次发表评论时,Giscus 才会为当前 pathname 创建 Discussion,这是正常行为。如果评论区没有显示,可依次检查 giscus 是否仍为 null、字段是否全部复制、Giscus App 授权、Discussions 开关、仓库可见性,以及浏览器网络或内容拦截扩展是否阻止了 giscus.app。

需要关闭评论时,将配置恢复为 giscus: null 即可,不需要删除组件或卸载依赖。已有 Discussion 会保留在 GitHub 中,但站点不再加载它们。

VitePress 基础配置 ​

src/.vitepress/config.ts 导出异步 UserConfigFn<DefaultTheme.Config>。它组合 site.config.ts、文章数据和 Markdown plugins,属于工程基础设施;只更换博客信息时不需要改这个文件。

顶层选项 ​

配置当前值或来源建议修改作用
langsiteConfig.site.language否设置文档和 HTML 语言
titlesiteConfig.site.title否设置全站标题
titleTemplate`:title | ${siteConfig.site.title}`按需组合页面标题与站点标题
descriptionsiteConfig.site.description否设置默认页面描述
basesiteConfig.site.base否设置 VitePress 部署基础路径
srcExclude["posts/**/*.md", "moments/**/*.md"]否不让文章和动态原稿直接生成 /posts 或 /moments 页面
cleanUrlstrue按需生成不带 .html 的公开 URL
lastUpdatedtrue按需让 VitePress 收集 Git 最后更新时间
appearancetrue按需启用 VitePress 明暗模式状态和切换能力
themeConfig.sidebar自动生成否根据文章 frontmatter 的 series 生成官方格式 sidebar
vite.plugins[tailwindcss()]否使用 Tailwind CSS 4 的 Vite plugin 处理主题样式

配置函数还会根据 command 区分环境:开发服务的系列侧栏包含草稿,生产构建会排除草稿;执行生产构建前调用 requireSiteUrl(),缺少 SITE_URL 时主动失败,避免发布带错误绝对地址的页面。

Markdown 选项 ​

这些能力由 VitePress 官方 Markdown 配置和 markdown-it plugins 提供,自定义主题只负责展示,不重复实现解析行为。

配置当前值作用
markdown.lineNumberstrue代码块显示行号
markdown.mathtrue启用数学公式解析
markdown.image.lazyLoadtrue为普通 Markdown 图片启用原生懒加载
markdown.codeCopyButton.tooltipText复制代码复制按钮默认提示文字
markdown.codeCopyButton.copiedText已复制复制成功后的提示文字
markdown.theme.lightgithub-light亮色模式 Shiki 代码主题
markdown.theme.darkgithub-dark暗色模式 Shiki 代码主题

Custom Containers 使用 VitePress 保留的英文关键字,界面标题改为中文:

英文关键字默认中文标题
info信息
note备注
tip提示
important重要
warning警告
danger危险
caution注意
details详细信息
image-grid图片布局
live-photoLive Photo

markdown.config(md) 依次注册下列 plugins:

plugin作用
markdown-it-task-lists将 Markdown 任务列表转换为可访问的 checkbox markup
imageGridPlugin解析 ::: image-grid 多图布局
livePhotoPlugin解析 ::: live-photo 并输出可播放的 Motion Photo
photoPreviewPlugin为普通图片和图片布局补充统一照片预览数据

具体写法分别见《使用 Markdown 扩展》《编排多图布局》和《使用 Live Photo》章节。

Sitemap、head 与构建钩子 ​

配置启用条件作用
sitemap.hostname存在 SITE_URL使用站点来源地址生成 sitemap
sitemap.transformItemssitemap 已启用从 sitemap 中排除 404 页面
head始终注入 favicon、manifest、RSS、Atom 和 JSON Feed 链接
transformHead每个页面生成 description、keywords、canonical、Open Graph 和 Twitter Card metadata
buildEnd构建结束调用 generateStaticAssets(config.outDir) 生成 Feed、robots 和 manifest 等静态文件

transformHead 优先使用动态页面参数中的 title、description、keywords、url 和 canonical,缺失时回退到页面数据及 siteConfig.site。带文章 slug 的页面输出 og:type=article,其它页面输出 website。

配置辅助函数 ​

site.config.ts 还导出三个辅助函数,通常不需要修改:

函数用途
isGiscusConfigured()检查 Giscus 必填字段是否完整,供评论组件决定是否加载
requireSiteUrl()在生产构建开始时确认 SITE_URL 已设置
withBasePath()为站内公开资源拼接规范化后的 SITE_BASE,外部 URL 保持不变

主题设计令牌 ​

项目参考 shadcn-vue 的语义主题方式,将可复用视觉值集中放在 src/.vitepress/theme/tailwind.css 的 @theme 中。组件优先使用 Tailwind utility,不直接读取具体颜色或尺寸数值。只有运行时生成的 DOM、复杂选择器或伪元素无法通过 utility 清晰表达时,才在对应组件中使用一个 <style scoped>,并直接读取相同的设计令牌。例如 ArticlePage.vue 使用标准 CSS Nesting 将 VitePress 生成的 Markdown DOM 规则收拢在 .article-content 下。现有 Tailwind CSS 4 + Vite 构建链可直接处理该语法,不需要额外的 nesting 插件或 PostCSS 配置。

颜色角色 ​

Tailwind 默认颜色命名空间已经关闭。通用 surface 使用基础 token / -foreground 配对,保证背景和其上的内容一起变化:

分组token用途
页面background / foreground页面画布与默认正文
容器card / card-foreground、popover / popover-foreground内容卡片与浮层
操作primary、secondary、accent 及各自 -foreground主要操作、次要表面、hover 与 active 状态
辅助muted / muted-foreground低强调表面与辅助文字
边界border、border-strong、ring容器边界、强边界与键盘焦点
遮罩overlay / overlay-foregrounddialog mask 及直接显示在 mask 上的内容
状态info、success、important、warning、destructive、caution 及各自 -foreground容器、Alerts 与草稿提示
代码领域code-background、code-card、code-muted-foreground、code-border、code-accent 和代码行状态固定深色代码画布

所有 --color-* 和阴影中的颜色必须使用 oklab()。亮色值定义在 @theme;@utility theme-dark 只覆盖确实不同的同名 token。根布局通过 dark:theme-dark 一次加载暗色值,组件继续使用 bg-background、text-foreground、border-border 等相同 utility。照片预览与搜索 dialog 的 mask 都使用 overlay;照片预览内直接落在 mask 上的图标和信息栏使用其通用配对 overlay-foreground,LIVE 标识和页面侧栏入口继续复用其它通用角色,不为单个组件建立专属色板。只有固定代码画布这类通用角色确实无法表达的功能才建立领域前缀,不能按页面或某次使用创建 header-*、search-* 一类颜色。

可维护尺度 ​

除颜色外,项目集中管理所有对博客有长期价值的设计尺度:

类别namespace当前用途
字体与字重font-*、font-weight-*中文正文字体、代码字体和字体包真实提供的 400 / 500
字号与行高text-*、leading-*基础 type scale、文章标题/正文/章节、紧凑 label、callout 和代码行高
字距tracking-*全局字距策略与 Live Photo 标识
间距与尺寸spacing、spacing-page-*、spacing-header、spacing-control-*、spacing-side-rail-*基础 4px spacing scale、页面 gutter、页头、控件和侧轨位置
圆角radius、radius-sm 至 radius-xl从单一基准派生的交互控件和容器圆角
容器container-*列表内容、文章正文、三轨布局、导航、搜索和照片详情宽度
响应式breakpoint-sm 至 breakpoint-xl项目实际使用的四个布局断点
层级z-index-content、z-index-control、z-index-navigation内容附属项、浮动控件和导航浮层
景深shadow-*、blur-*卡片、dialog、磨玻璃预览和代码 focus blur
媒体aspect-*横图、竖图、混排图和文章封面比例
动效duration-*、ease-*、animate-*默认过渡、即时缩放、慢速宽度变化、loading 和 Live Photo

基础数值尺度使用 Tailwind 熟悉的 sm、md、lg;只有跨组件且用途稳定的值才使用 page-gutter、side-rail-top 这类语义名称。项目没有表单系统、统计图表或 dashboard sidebar,因此不会照搬 shadcn-vue 中没有实际消费者的 token;照片详情宽度属于稳定布局尺寸,可以保留 container-photo-inspector,但这不意味着照片功能需要独立颜色领域。

新增与修改规则 ​

调整全站视觉时先修改已有 token。确需新增时,先确认它满足以下条件:在多个位置重复,或代表不会随组件名称变化的稳定语义;名称描述角色而非颜色值或当前页面;有源码消费者和必要的回归断言。surface 颜色必须补齐 -foreground 配对,独立领域内部也遵循 background、foreground、card、muted、border、accent 等一致后缀。

视口 calc()、响应内容的 minmax() grid track、伪元素 content 和组合 transition property 依赖上下文,可以保留 arbitrary value。普通字号、字距、圆角、模糊、图片比例和动画已有命名尺度,不得再写 arbitrary value。不要使用 Tailwind 内置色板或任意硬编码颜色。确需 scoped CSS 时,每个组件最多使用一个 <style scoped>,不得使用全局选择器、Tailwind 指令、CSS Modules、CSS-in-JS 或内联 style;pnpm audit:styles 会检查这些边界、必需 namespace、颜色配对和旧 token 回归。

发布前检查 ​

发布前至少确认:

  • site.config.ts 中的站点名称、简介、关键词和作者信息已替换。
  • 导航链接和 homeSocials 中没有无效占位地址。
  • favicon 和 manifest 图标文件真实存在。
  • workflow 的 SITE_URL、SITE_BASE 与 GitHub Pages 实际部署方式一致。
  • 不使用评论时 giscus 为 null;使用时全部字段来自目标仓库的 Giscus 配置。
  • 修改 config.ts 后,相关 Markdown、动态路由、SEO 或静态生成测试同步更新。