Lee's Blog
  • 首页
  • 博客
  • 作品
  • 成长
  • 学习
  • 打榜
  • 练习
  • 关于
登录 / 注册
✦

保持联系

关注我的最新动态

GitHubbilibili

© 2026 Lee's Blog

首页/博客/博客开发/从零搭建一个带风后奇门的个人博客
从零搭建一个带风后奇门的个人博客
博客开发2026年5月19日5 分钟阅读

从零搭建一个带风后奇门的个人博客

Next.js 16 + Tailwind v4 + Prisma + 奇门遁甲罗盘。从技术选型到踩坑复盘,一篇全栈博客开发的完整记录。

前端后端架构教程
X微博

为什么要自建博客?

在此之前我用过 Hexo、WordPress,甚至手写过静态 HTML。它们各有各的好,但都有一个共同的问题:我不能完全控制体验。

我想要一个能自由设计每个像素的个人空间。框架博客做不到这些。

于是我决定从零搭一个。

技术选型

框架:Next.js 16 (App Router)

选 Next.js 而不是其他框架的理由很简单:Server Components。博客页面大部分是纯展示,不需要客户端 JS。RSC 让首屏加载几乎零 JS,只有交互部分才 hydrate。

样式:Tailwind CSS v4 + 自定义主题

v4 最大的变化是从配置文件(tailwind.config.ts)迁移到了纯 CSS 的 @theme 指令。配合 CSS 自定义属性,换主题只需要改几个变量的值。

数据库:SQLite → PostgreSQL(按需切换)

开发阶段 SQLite 零配置,部署前跑 bash scripts/switch-to-pg.sh 切换到 PostgreSQL。Prisma 做抽象层,切换数据库只需要改一行 provider。

认证:NextAuth v5 (Credentials + JWT)

Admin 系统需要认证。NextAuth v5 的 Credentials Provider 配合 JWT,轻量够用。没有 OAuth 的复杂跳转。

设计系统——黑金风格的诞生

最初的设计方案是深空蓝紫配色,像这样:

`css :root { --accent-cyan: #00d4ff; --accent-blue: #3b82f6; --accent-purple: #7c3aed; } `

后来觉得蓝紫太冷淡,换成了黑金。金色在暗色背景上有天然的奢华感,而且——说实话——金色代码更好看。

`css :root { --gold-dark: #8b6914; --gold-mid: #c99a2a; --gold-bright: #f5c71a; --gold-highlight: #ffe87c; } `

毛玻璃卡片

文章卡片的毛玻璃效果是用两层 linear-gradient 叠加 backdrop-filter: blur 实现的:

`css .glass-card { background: linear-gradient(145deg, rgba(8,12,30,0.65), rgba(15,12,25,0.55)), linear-gradient(135deg, rgba(139,105,20,0.08), rgba(245,199,26,0.03)); backdrop-filter: blur(16px); border: 1px solid rgba(245, 199, 26, 0.1); } `

注意:backdrop-filter 在 Safari 上有严重的渲染 bug,会让卡片做「圆周运动」。如果你的卡片在 Safari 上飘走了,去掉 backdrop-filter 就好。

奇门遁甲罗盘——最「不务正业」的 Hero

这个博客最引人注目的部分不是代码质量,而是首页那个旋转的奇门遁甲罗盘。

七层同心圆

罗盘由 7 层 SVG 同心圆环组成,从外到内分别是:

层 内容 旋转
1 先天八卦(乾兑离震巽坎艮坤) 顺时针 120s
2 十二地支(子丑寅卯辰巳午未申酉戌亥) 逆时针 90s
3 十天干(甲乙丙丁戊己庚辛壬癸) 顺时针 70s
4 后天八卦(离坤兑乾坎艮震巽) 逆时针 55s
5 九星(蓬任冲辅英芮柱心禽) 顺时针 45s
6 八门(休生伤杜景死惊开) 逆时针 35s
7 八神(符蛇阴合虎玄地天) 顺时针 25s

每一层都在以不同的速度旋转,中心是太极图。搭配轨道粒子和鼠标视差效果,形成独特的视觉标识。

踩坑:CSS class 冲突

最离谱的 bug 是这个:Tailwind v4 有一个内置 utility 叫 ring-1(设置 box-shadow),而我的罗盘环也用了 .ring-1 作为 class 名。

结果是 admin 页面所有用了 <Card> 组件的地方都继承了旋转动画——管理员在后台看到的文章卡片正在以 120 秒一圈的速度缓缓作圆周运动。

修复很简单:把 class 名改成 .hr-1(hero-ring 的缩写)。

架构决策

Server Component 直连 Prisma vs API 路由

前台页面全部用 Server Component 直连 Prisma,没有任何 API 中间层:

`typescript // app/(public)/blog/page.tsx — Server Component export default async function BlogPage() { const posts = await prisma.post.findMany({ where: { status: "PUBLISHED" }, orderBy: { publishedAt: "desc" }, }) return } `

这样做的理由:博客是读多写少的场景,Server Component 在服务端直接查库,不需要经过 HTTP 往返。

Admin 系统则用 API 路由,因为需要鉴权和写操作。

shadcn/ui 搭 Admin

Admin UI 全部用 shadcn/ui 的组件拼装。17 个组件(Button、Card、Table、Dialog 等)覆盖了所有后台需求,不需要自己写 UI 库。

移动端适配

最大的坑是 100vh。在手机上,浏览器的地址栏会动态改变视口高度——展开时 100vh 正确,收起时底部会有空白。

解决:用 100dvh 替代 100vh。

`css .snap-page { height: 100dvh; } `

Admin 侧边栏在 768px 以下从固定侧栏变为顶部导航条。

踩坑总结

1. ring-1 与 Tailwind utility 冲突

整个开发过程中最搞笑的 bug。Admin 卡片在做圆周运动。

2. backdrop-filter 在 Safari 上让元素「游泳」

macOS Safari 的 backdrop-filter 实现有 bug,会让应用了 blur 的元素在滚动时产生位移。解决方案:在 Safari 上不启用 backdrop-filter。

3. Middleware 里不能用 Prisma

Next.js 的 Middleware 运行在 Edge Runtime,不支持 Node.js 原生模块。Prisma 在 Edge 上只能用 WASM 引擎,但 SQLite 驱动不兼容。

解决方案:Middleware 只做简单的 cookie 检查,真正的鉴权在 API 路由里用 auth() 完成。

4. Streaming SSR 让 loading 状态复杂化

Server Component 的流式渲染意味着页面内容分段到达。如果 loading.tsx 没有 CSS 样式,用户会看到白屏。一个小金环 spinner 解决了这个问题。

总结

这个博客花了几周时间开发,从设计到部署全栈覆盖。最满意的地方不是代码,而是那个奇门遁甲罗盘——它让这个博客有了唯一性。

技术栈选型上,Next.js 16 App Router + Server Components 被证明是博客类网站的最佳选择:性能好、开发体验流畅、生态成熟。

所有代码都开源了。如果对某个实现细节感兴趣,欢迎在评论区留言讨论。

← 上一篇奶奶说我长得越来越像女孩子了下一篇 →运维日志——偷摸修BUG,无感发布

相关文章

  • 一次登录 / 资料 / 头像的全面体检——5 个用户报告 + curl 抓出的真问题约 9 分钟
  • 用户登录后看不到自己的头像——一次 DOM 顺序撞车约 5 分钟
  • TOC 悬浮折腾记:6 次 commit 才彻底搞定约 6 分钟

评论

需要登录账号才能发表评论。

  • 加载中…

本页内容

  • 为什么要自建博客?
  • 技术选型
  • 框架:Next.js 16 (App Router)
  • 样式:Tailwind CSS v4 + 自定义主题
  • 数据库:SQLite → PostgreSQL(按需切换)
  • 认证:NextAuth v5 (Credentials + JWT)
  • 设计系统——黑金风格的诞生
  • 毛玻璃卡片
  • 奇门遁甲罗盘——最「不务正业」的 Hero
  • 七层同心圆
  • 踩坑:CSS class 冲突
  • 架构决策
  • Server Component 直连 Prisma vs API 路由
  • shadcn/ui 搭 Admin
  • 移动端适配
  • 踩坑总结
  • 1. `ring-1` 与 Tailwind utility 冲突
  • 2. `backdrop-filter` 在 Safari 上让元素「游泳」
  • 3. Middleware 里不能用 Prisma
  • 4. Streaming SSR 让 loading 状态复杂化
  • 总结