这个博客是怎么搭起来的:Next.js 与 Markdown

3 分钟读完前端系列

决定重写博客之后,我给自己定了三个约束:内容必须是纯 Markdown 文件,样式要好看得有辨识度,标签和搜索要开箱即用。这篇文章记录实现的过程,也方便未来的自己翻修。

技术选型

需求选择理由
框架Next.js App Router静态生成,部署简单
样式Tailwind CSS v4写惯了
组件shadcn/ui源码进仓库,随便改
内容content/posts/*.md纯文件,随时可以搬走

没有用 headless CMS,没有用数据库。一篇文章就是一个文件,frontmatter 写元信息:

yaml
---
title: 文章标题
description: 一句话摘要
date: 2026-09-05
tags: [前端, Next.js]
pinned: true
---

正文从这里开始。

内容加载

读取文件用 gray-matter 解析 frontmatter,渲染用 react-markdown 加上 GFM 插件和 rehype-highlight:

ts
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)
  • 站内链接的引用计数
  • 从读书笔记自动生成摘录卡

代码就在这个仓库里,感兴趣可以翻翻。

收录于 前端 系列