从静态 HTML 博客迁移到 Next.js 的记录
记录我把原来的静态博客逐步迁移到 Next.js 的过程,包括页面结构、组件拆分、样式重构和后续优化方向。
为什么要迁移
这个博客最早是用纯 HTML/CSS/JS 写的,每个页面一个 HTML 文件,样式全部手写。刚开始内容少的时候还好,但随着文章越来越多,每次改导航栏都要改十几个文件,维护起来非常痛苦。
另外静态 HTML 没有组件化的能力,公共部分只能靠复制粘贴。导航栏、页脚、侧边栏这些内容在每个页面都重复了一遍,改起来很容易漏掉。
最后决定迁移到 Next.js,主要是看中了它的 App Router、组件化开发、以及 static export 能力——可以继续部署在 Cloudflare Pages 上,不需要改部署方案。
迁移过程
路由设计
原来的静态站用的是文件系统路由,每个页面一个 HTML 文件,比如 /about.html、/posts/xxx.html。Next.js 的 App Router 虽然也是文件系统路由,但处理方式不同。
文章详情页用 [slug] 动态路由,配合 generateStaticParams 在构建时生成所有静态页面。分类和标签页面也做了类似的处理。整体路由结构和原来基本一致,用户感知不到变化。
组件拆分
迁移过程中最大的工作量是把公共部分抽成组件。导航栏、侧边栏、页脚、文章卡片这些都做成了独立的 React 组件。组件化之后,改一个地方全局生效,比之前方便太多了。
// components/Sidebar.tsx
export default function Sidebar() {
const pathname = usePathname();
return (
<aside className="hidden sm:flex sm:flex-col sticky top-0 h-screen w-[260px]">
{/* 导航内容 */}
</aside>
);
}样式迁移
原来的博客用的是自定义 CSS,每个页面一套样式。迁移到 Tailwind CSS 后,样式写在组件里,不用再维护单独的 CSS 文件。Tailwind v4 的 @theme 指令让设计令牌的管理变得很直观。
踩坑记录
gray-matter 日期解析问题
gray-matter 会自动把 ISO 格式的日期字符串解析成 JavaScript Date 对象。一开始没注意到这个问题,导致 date.slice(0, 10) 报错,因为 Date 对象没有 slice 方法。
解决方法是用 String(data.date).slice(0, 10) 强制转成字符串再截取。
静态导出和环境变量
Next.js 的 output: "export" 模式下,process.env 在运行时不可用。如果代码里依赖了环境变量,构建时会被替换成 undefined。需要在 next.config.ts 里通过 env 字段硬编码,或者改用构建时确定的值。
后续计划
迁移完成后,后续准备做的事情:
- 支持 MDX 文章,不再把正文写在代码里
- 添加文章目录 TOC
- 代码块高亮
- RSS 订阅
- 全局搜索功能
总体来说,迁移到 Next.js 的体验还是很满意的。开发效率提升了很多,后续加功能也比以前方便。
相关推荐
互动