这个博客是怎么搭起来的:Next.js 与 Markdown
决定重写博客之后,我给自己定了三个约束:内容必须是纯 Markdown 文件,样式要好看得有辨识度,标签和搜索要开箱即用。这篇文章记录实现的过程,也方便未来的自己翻修。
技术选型
| 需求 | 选择 | 理由 |
|---|---|---|
| 框架 | Next.js App Router | 静态生成,部署简单 |
| 样式 | Tailwind CSS v4 | 写惯了 |
| 组件 | shadcn/ui | 源码进仓库,随便改 |
| 内容 | content/posts/*.md | 纯文件,随时可以搬走 |
没有用 headless CMS,没有用数据库。一篇文章就是一个文件,frontmatter 写元信息:
---
title: 文章标题
description: 一句话摘要
date: 2026-09-05
tags: [前端, Next.js]
pinned: true
---
正文从这里开始。
内容加载
读取文件用 gray-matter 解析 frontmatter,渲染用 react-markdown 加上 GFM 插件和 rehype-highlight:
const raw = fs.readFileSync(path.join(POSTS_DIR, fileName), "utf-8");
const { data, content } = matter(raw);
return {
slug: fileName.replace(/\.md$/, ""),
title: String(data.title ?? ""),
date: normalizeDate(data.date),
tags: Array.isArray(data.tags) ? data.tags.map(String) : [],
content,
};
文章列表按日期倒序,标签在构建时聚合计数。因为都是静态生成,搜索干脆放在了浏览器端做:数据随页面下发,输入即过滤,不需要任何接口。
阅读时长的估算规则很粗糙但够用:中文按每分钟 350 字,英文按每分钟 200 词,两者相加取整。
设计
主题叫「蓝黑墨水与稿纸」。
颜色只有四个角色:冷调纸白做背景,蓝黑墨色做正文,钢笔靛蓝做唯一强调色,深黛色留给夜间模式。刻意避开了米色纸底配赤陶橘的常见组合,那套配色太眼熟了。
字体用霞鹜文楷做标题和正文,楷体的手写感贴合「稿纸」的隐喻;代码块用等宽字体。落地页的背景铺了一层极淡的方格,模拟稿纸的格子,标题末尾有一个缓慢闪烁的墨块光标,像正在落笔。
动效只有一处:首屏文字以「墨迹入纸」的方式浮现,一次播放即止,并且尊重系统的减弱动态设置。
还没做但想做的
- RSS 订阅源
- 文章目录(TOC)
- 站内链接的引用计数
- 从读书笔记自动生成摘录卡
代码就在这个仓库里,感兴趣可以翻翻。
收录于 前端 系列