这个博客是怎么搭的
这一篇是写给你的——如果你 clone 了这个项目,它会告诉你东西都在哪。
你只需要改一个文件#
src/config.ts。里面的 site、author、nav 三项改完就能上线:
export const site: SiteConfig = {
title: '你的站名',
tagline: '一句话说清这个站是什么。',
url: 'https://example.com', // 部署前填,不留斜杠
lang: 'zh-CN', // 别改错——浏览器的中文标点规则依赖它
author: { name: '你的名字', bio: '一句话介绍自己。' },
// …
};
其余全部有可用的默认值,而且默认值本身就是完整站点,不是占位符。
你现在看到的这些文章和知识库条目就是示例内容——它们是真的能读的,
不是 lorem ipsum。删掉它们换成你自己的即可。
东西都在哪#
src/
├── config.ts 你唯一必须改的文件
├── content/
│ ├── posts/ 文章。按时间排
│ └── wiki/ 知识层。按主题互链
├── layouts/ 页面骨架
├── components/ 组件
├── pages/ 路由
├── lib/ 纯逻辑(可测试,不依赖 Astro)
│ ├── negotiate/ Accept 头解析——[[内容协商]] 的实现
│ └── wiki/ 链接图、体检、llms.txt 生成
└── styles/
├── tokens.css 设计令牌
├── base.css 基线排版(含 [[中文排版]] 的那些修正)
└── site.css 布局与组件
两种内容,两种组织方式#
文章放在 src/content/posts/,按时间排列,是「流」。
知识库条目放在 src/content/wiki/,按主题互链,是「网」。
它们的区别不是格式,是读者找东西的方式:想看你最近写了什么就翻文章, 想搞清某个概念就查知识层。两边的条目地位相同,可以互相引用。
用 [[方括号]] 连起来#
在任何地方写 [[目标]],就会生成一条链接:
见 [[内容协商]] 一节。
支持三种写法:
| 写法 | 效果 |
|---|---|
[[内容协商]] | 链接,显示文本即目标名 |
[[内容协商|那篇]] | 自定义显示文本 |
[[内容协商#为什么]] | 指向页内某小节 |
目标可以写 slug,也可以写标题——你大概不会记得每篇的 slug 是什么。 解析时大小写和空格都不敏感。
写错了不会静默失败:构建时会报一条 broken-wikilink 错误,
并告诉你哪个页面引用了什么。
构建时会做体检#
每次构建会跑一遍知识库体检,输出在控制台。分三级:
- 错误:断链、两个页面抢同一个 URL、文章占用
/about/等系统路由、 引用了没登记的来源、复核状态与正文对不上。 会让构建失败(可在配置里关掉) - 警告:孤儿页(没有任何页面指向它)、缺摘要、空正文、
同一关系在正文与
related里各写了一次 - 提示:摘要过长之类的建议
这不是可选的装饰。 一个由人(或 agent)持续维护的知识库, 最容易的结局是慢慢烂掉——改了标题没改引用、删了页面留下断链。 机械的检查必须能进 CI,否则「知识库」会退化成「一堆文件」。
完整的规则表在 AGENTS.md——那份是写给 agent 看的,改规则时两边要一起改。
给 AI 读者那一份#
这一站有两个出口,服务两类读者:
Markdown 孪生文件。 每篇文章和知识页都有可直接访问的 .md URL。
在支持内容协商的部署平台上,请求页面 URL 时带上 Accept: text/markdown
也会得到 markdown;本站使用 GitHub Pages,因此应直接访问 .md 链接。
原理和托管限制见 内容协商。
目录与全文。 /llms.txt 是给 agent 看的目录(标题 + 一句话说明),
/llms-full.txt 是全文内联版。每个页面还有 .md 孪生文件,
比如 /how-this-works.md。
需要说明的是:llms.txt 的实际效果被高估了——
Ahrefs 实测 13.7 万个域名里 97% 的 llms.txt 从未被请求过。
本站生成它是因为零成本,但主要依靠显式 .md 链接、内容清单和干净的 HTML。
部署#
静态产物,任何静态托管都能跑。但内容协商需要一层边缘函数—— 因为静态托管不解析请求头,它只会把文件原样吐出来。
项目里带了三个平台的现成实现,选你用的那个:
| 平台 | 边缘函数 | 平台配置 |
|---|---|---|
| Cloudflare Pages | functions/[[path]].ts | public/_headers(会被拷进产物) |
| Netlify | netlify/edge-functions/negotiate.ts | 无额外配置 |
| Vercel | middleware.ts | vercel.json |
不想要这一层也没关系,站点照常工作,只是 agent 拿到的是 HTML 而不是 markdown。
详细说明#
这一页也有 markdown 版本:/letterpress/how-this-works.md
直接打开上面的 .md 链接即可读取;在支持内容协商的部署平台上, 也可以对页面 URL 发送 Accept: text/markdown。