博客设计与搭建:从零构建渐变风格个人博客

项目概述

一直想有一个属于自己的地方,记录技术思考和日常感悟。试过各种平台,最终还是觉得自建博客最自由。这篇文章记录整个博客从设计到搭建的完整过程。

技术选型

博客的定位是混合型(技术 + 随笔 + 生活),所以技术栈需要兼顾写作体验和开发灵活性:

  • Next.js 14 — App Router + 服务端组件,零 bundle 开销
  • MDX — Markdown + React 组件,文件系统存储,写作像写文档
  • Tailwind CSS — 原子化 CSS,快速实现设计稿
  • TypeScript — 类型安全,减少低级错误
  • Vercel — 一键部署,自动 CI/CD

不使用数据库,所有内容都存在文件系统里。纯前端,无后端 API,保持极简。

视觉风格:渐变 + 玻璃拟态

整体采用紫色渐变为主色调,搭配玻璃拟态(Glassmorphism)卡片效果。

配色方案

用途颜色值
主渐变#667eea#764ba2
背景渐变#f0e6ff#faf5ff
深色 Footer#1a1a2e
卡片背景rgba(255,255,255,0.7) + 毛玻璃模糊
正文文本#333

核心设计特征

  • 玻璃拟态卡片:半透明白底 + backdrop-filter: blur(10px)
  • 渐变标签:紫渐变胶囊形状,白字圆角
  • 大圆角:16px 卡片圆角,8px 小组件圆角
  • 柔和阴影rgba(118,75,162,0.08) 紫色调阴影
  • 系统字体system-ui,加载零延迟

架构设计

数据流

content/*.mdx → lib/posts.ts (解析 frontmatter) → 首页/标签页渲染
                              ↓
                    app/posts/[slug]/page.tsx → 文章详情渲染 (MDX)

项目结构

blog/
├── app/
│   ├── posts/[slug]/page.tsx    # 文章详情页
│   ├── tags/[tag]/page.tsx      # 标签筛选页
│   ├── layout.tsx               # 全局布局
│   ├── page.tsx                 # 首页
│   └── not-found.tsx            # 404 页面
├── components/
│   ├── Header.tsx               # 导航栏
│   ├── Footer.tsx               # 页脚
│   ├── PostCard.tsx             # 文章卡片
│   ├── SearchBar.tsx            # 搜索组件
│   └── MDXComponents.tsx        # MDX 自定义组件
├── content/                     # 文章文件
└── lib/posts.ts                 # MDX 解析工具

MDX 渲染管线

每篇文章的渲染经历了三层处理:

  1. 文件读取fs.readFileSync 读取 .mdx 文件
  2. 编译compileMDX 解析 frontmatter,应用 remark/rehype 插件
  3. 组件注入 — 自定义 MDXComponents 覆盖默认 HTML 元素样式
const { content } = await compileMDX({
  source,
  options: {
    parseFrontmatter: true,
    mdxOptions: {
      remarkPlugins: [remarkGfm],
      rehypePlugins: [rehypeSlug, rehypeHighlight],
    },
  },
  components,
});

💡 关键经验:next-mdx-remote v6 的 API 与旧版本不同,使用 compileMDX 而非 serialize,插件需要通过 mdxOptions 传入。

页面实现

首页

渐变紫色背景 + Hero 标语文字,文章以响应式 auto-fill 网格排列,每行 2-3 张玻璃卡片。

文章详情页

标题区淡紫渐变背景,正文 720px 居中放在白色玻璃卡片内:

  • 标题:紫色系大字号
  • 段落:1.8 行高
  • 引用块:紫色左边框 + 淡紫渐变背景
  • 代码块:atom-one-dark 主题语法高亮

标签筛选

与首页相同布局,通过 URL 参数过滤文章列表。

踩坑记录

MDX 组件未生效

最初直接用 <MDXRemote source={source} /> 渲染,自定义组件完全没有生效。原因是:

  1. 没有传入 components prop 给 MDXRemote
  2. next.config.mjs 中的 remark/rehype 插件只对路由级 MDX 生效,不影响 next-mdx-remote

修复方式是使用 compileMDX 并显式传入自定义组件和插件配置。

代码块看不清

代码块背景是深色 #1a1a2e,但忘记导入 highlight.js 的主题 CSS,导致文字几乎是不可见的浅灰色。解决方案是在 globals.css 中导入 atom-one-dark 主题:

@import 'highlight.js/styles/atom-one-dark.css';

当前功能清单

  • 文章列表页(按日期倒序)
  • 文章详情页(MDX 渲染 + 语法高亮)
  • 标签分类筛选
  • 搜索功能
  • 响应式设计(移动端友好)
  • 自定义 404 页面

后续可能考虑评论系统,但目前保持极简就好。

标签: