我把最近这套博客主题单独抽出来,整理成了一个可以复用的开源项目:Astro Theme Inkstone。
它的定位很明确:给喜欢在 Obsidian 里写作、希望用 Astro 发布静态博客的人,一个安静、耐看、中文友好,而且不需要维护复杂后端的主题起点。
项目地址:github.com/moxiaonai/astro-theme-inkstone
为什么叫 Inkstone
Inkstone 是“砚台”。
我很喜欢这个意象。一个博客主题不应该只是某种短期视觉效果,它更像一件长期放在桌上的写作器物:稳定、克制、耐看,最好还能让你愿意反复打开它,慢慢写,慢慢改,慢慢沉淀。
这个名字里有三层意思:
- Ink 是写作、表达和知识流动。
- Stone 是稳定、克制和长期维护。
- Obsidian-friendly 则对应本地 Markdown 知识库和静态发布工作流。
如果你想搭一个中文技术博客,既能写文章,也能放项目、归档、标签、搜索和 RSS,Inkstone 会是一个很轻的起点。
它解决的不是“怎么建站”,而是“怎么长期写”
很多博客模板第一眼很好看,但真正写一段时间后,问题会变成这些:
- 文章文件放在哪里才舒服?
- 图片怎么管理,才能同时适配 Obsidian 和线上站点?
- 标签、归档、搜索、RSS 要不要自己补?
- 站点信息、导航、项目卡片改起来会不会散落在各处?
- 深浅色切换、SEO、sitemap、
llms.txt这些细节要不要反复重做?
Inkstone 的目标是把这些常见问题先整理好。你可以直接把项目根目录作为 Obsidian vault 打开,在 src/content/blog 写 Markdown / MDX,把图片放进 public/images/posts,然后交给 Astro 构建成纯静态站点。
写作仍然发生在本地,发布则保持简单。
适合谁
它更适合这些场景:
- 你习惯用 Obsidian 管理草稿、笔记和文章。
- 你想要一个静态博客,而不是数据库驱动的 CMS。
- 你主要写中文技术文章,希望排版、行距和阅读宽度默认舒服。
- 你希望博客自带标签、归档、搜索、项目页、RSS 和 SEO。
- 你不想把主题做得很重,但希望它有一点视觉记忆点。
- 你希望未来可以部署到 Cloudflare Pages、Vercel、Netlify 或 GitHub Pages。
它不是一个大型内容平台,也不追求把每个功能都做成配置项。它更像一套清晰的博客骨架:默认能用,结构容易读,样式容易改。
核心功能
Inkstone 目前包含一套完整的个人博客页面:
- 首页
- 博客列表
- 文章详情
- 标签页
- 年份归档
- 项目页
- 搜索页
- 关于页
- 赞助页
- RSS
- sitemap
- robots
llms.txtcontent-index.json
文章由 Astro Content Collections 管理,frontmatter 支持标题、摘要、发布日期、更新日期、标签、封面图、草稿状态和精选标记。
---
title: "文章标题"
description: "一句话摘要"
pubDate: 2026-09-20
updatedDate: 2026-09-20
tags: ["Astro", "Obsidian", "Markdown"]
draft: false
cover: "/images/posts/example.png"
featured: false
---
为了方便在 Obsidian 里先写草稿,缺少标题、缺少发布日期,或者设置了 draft: true 的文章不会进入公开文章列表。
Light / Dark 的视觉细节
主题内置 Light / Dark 双主题,支持系统偏好、用户手动选择和 localStorage 持久化。
我给主题切换加了一个从按钮位置展开和收起的动画。它不是简单淡入淡出,而是更像一滴墨从右上角扩散出来:切到深色时,暗色页面从按钮处铺开;切回浅色时,旧的暗色页面再收回按钮附近。
这个效果原本可以用 View Transition API 做,但我在实际调试里遇到过 dark 到 light 时短暂闪黑的问题。最后改成了自绘 DOM 遮罩:用一个临时层克隆当前页面,再通过 clip-path: circle(…) 控制圆形范围。这样动画方向可控,也避开了浏览器截图层带来的偶发闪烁。
这也是 Inkstone 视觉上比较有记忆点的一处细节:它不抢内容,但在你切换主题时,会让主题的名字和气质对上。
本地搜索和内容发现
Inkstone 的搜索是纯本地搜索。构建时生成文章索引,前端直接搜索标题、摘要、日期和标签,不需要 Algolia、数据库或第三方服务。
同时,它默认补好了面向搜索引擎、社交平台和 AI 工具的内容发现入口:
- canonical URL
- Open Graph
- Twitter Card
- 文章 JSON-LD
- RSS
- sitemap
- robots
llms.txtcontent-index.json
其中 llms.txt 会输出站点说明、核心页面、文章列表、标签和项目;content-index.json 则提供结构化内容索引,方便 AI 工具读取和引用。
快速开始
推荐使用 Node.js 20+ 和 pnpm 10+。
git clone git@github.com:moxiaonai/astro-theme-inkstone.git
cd astro-theme-inkstone
pnpm install
pnpm dev
启动后访问:
http://127.0.0.1:4321/
常用命令:
pnpm dev # 本地开发
pnpm build # 构建静态站点到 dist
pnpm preview # 本地预览构建结果
pnpm obsidian # macOS 下用 Obsidian 打开当前目录
怎么改成自己的博客
大多数个性化配置集中在 src/theme/site.ts。你通常先改这里,就能替换站点标题、作者、域名、导航、首页文案、项目卡片和友情链接。
常见入口如下:
| 想修改 | 文件 |
|---|---|
| 站点标题、副标题、描述、域名 | src/theme/site.ts |
| 作者名、作者页地址 | src/theme/site.ts |
| 首页 Hero 文案 | src/theme/site.ts |
| 导航菜单 | src/theme/site.ts |
| 社交链接 | src/theme/site.ts |
| 项目卡片 | src/theme/site.ts |
| 颜色、字体、间距、圆角 | src/theme/styles/theme.css |
| Header、Footer、Logo、卡片组件 | src/theme/components/* |
| 文章内容 | src/content/blog |
| 文章图片 | public/images/posts |
| 项目图片 | public/images/projects |
部署前记得把 site.url 和 astro.config.mjs 里的 site 改成你的真实域名。它会影响 canonical URL、RSS、sitemap、Open Graph 图片和 llms.txt 中的链接。
项目结构
.
├── .obsidian/
│ └── app.json
├── public/
│ ├── _redirects
│ ├── favicon.svg
│ └── images/
│ ├── posts/
│ ├── projects/
│ ├── site/
│ └── theme/
├── src/
│ ├── content/
│ │ └── blog/
│ ├── layouts/
│ ├── lib/
│ ├── pages/
│ └── theme/
│ ├── components/
│ ├── styles/
│ ├── site.ts
│ └── README.md
├── astro.config.mjs
├── package.json
└── README.md
这套结构的重点是把“内容”和“主题”分清楚:文章在 src/content/blog,主题组件和样式在 src/theme,站点配置集中在 src/theme/site.ts。后面无论是写文章、换图片,还是调整视觉,都比较容易找到入口。
我希望它保持什么样
Inkstone 会尽量保持轻量。能用 Astro、Markdown、CSS 和少量原生 JavaScript 解决的事情,就不引入额外依赖。
我希望它长期保持这几个方向:
- 中文阅读体验优先。
- 本地写作流程优先。
- 静态部署优先。
- 结构清晰,方便自己二次修改。
- 对搜索引擎、RSS 阅读器和 AI 工具友好。
- 视觉安静,但有一点自己的性格。
如果你也想把 Obsidian 里的内容发布成一个长期维护的个人站点,可以直接拿它开始改。
项目地址在这里:Astro Theme Inkstone。