跳到正文

博客

博客不需要你写任何页面文件,一切都从文章本身生成。

文章

把 markdown 文件放在 posts/ 下。目录名可配置。

---
title: 你好,VuePress
date: 2026-01-12
tags:
  - vuepress
  - release
excerpt: 这个主题为什么存在。
---

date 可以省略:省略时主题回退到文件的 git 创建时间,所以文章永远不会从归档里消失。

Frontmatter类型说明
titlestring文章标题
datestring | Date发布日期,用于排序
tagsstring | string[]标签,每个标签会得到一个页面
excerptstring列表中展示的摘要
stickyboolean | number置顶,数字表示顺序
blogfalse把该文件排除在博客之外

每篇文章还会在日期旁显示预估阅读时间。估算在构建期完成(200 词/分钟,CJK 按字计), 并通过 blog.readingTime 本地化:

blog: {
  // `:minutes` 会被替换为数字;默认是 `:minutes min read`。
  readingTime: '预计阅读 :minutes 分钟',
}

生成的页面

主题会根据你的文章创建:

  • blog.postsPath 处的列表页,开启分页时还有 /page/2/、/page/3/ …
  • blog.tagsPath 下每个标签一个页面
  • blog.tagsPath 处的标签总览
  • blog.archivesPath 处的归档,按年、按月分组

在导航栏加一个指向 /blog/ 的链接就能暴露它。

标签页位于由标签推导出的 ASCII slug:转小写、空格变 -,其余字符丢弃。丢字符的标签 会追加短哈希(C++ → c-2ead0510、中文标签 → tag-c42f0ba0),保证两个不同标签 永不撞车。这条规则由 Node 与客户端共用,所以生成的目录和指向它的链接始终一致。

选项

theme: githubTheme({
  blog: {
    postsDir: 'posts',
    postsPath: '/blog/',
    tagsPath: '/blog/tags/',
    archivesPath: '/blog/archives/',
    perPage: 4,
    pagination: true,
    title: '博客',
    intro: '关于这个主题的一些笔记。',
  },
})
选项默认值说明
postsDirposts读取文章的目录
postsPath/blog/生成的列表路由
tagsPath/blog/tags/标签页路由
archivesPath/blog/archives/归档路由
perPage12列表每页文章数
paginationtrue是否把列表分页
titleBlog列表标题
intro''标题下方的段落
readingTime:minutes min read日期旁的阅读时间文案

用 blog: false 整体关闭博客。

两个 locale,一个文章目录
postsDir 相对 locale 目录解析,所以 /zh/ 下的 posts 指的是 zh/posts/。 把两个 locale 指向同一个目录,会让彼此互相收录对方的文章、并给对方语言的标签生成 归档;主题在构建期打印一条告警而不是失败,因为共享单一目录虽然少见,但也是合法用法。

视图

主题只注册一个布局,靠 frontmatter 选择博客视图,所以每个生成页面都保持同一套外壳 —— 导航栏、页脚、侧边栏。

blogView渲染
blog分页的文章列表
tag路由中标签对应的文章
tags所有标签及数量
archives按年、按月分组的文章

在你自己的页面上设置它,即可复用某个视图:

---
blogView: archives
---

组件

GithubPostList 与 GithubPostItem 由主题导出,自定义页面可以渲染自己的列表:

<script setup>
import { GithubPostList, usePosts } from 'vuepress-theme-github/client'

const posts = usePosts()
</script>

<template>
  <GithubPostList :posts="posts.slice(0, 5)" />
</template>