建站与专题← 返回文章列表

基于 Next.js App Router 与 Nextra 4 构建静态博客

记录基于 Next.js App Router 与 Nextra 4 搭建个人静态博客的工程方案,包括 MDX 组件注入、Pagefind 离线检索、Sitemap 自动化生成与 Docker 多阶段构建。

LJ
李建辉·前端全干工程师

· 9 分钟

本页目录展开 / 收起

读完你能做什么

  • 解释 MDX 文件如何经过 Next.js 与 Nextra 生成静态页面。
  • 配置组件映射、全文检索、站点地图和静态导出。
  • 用生产构建而不是开发服务器验证真实部署产物。

建站流程应围绕最终产物设计。开发模式只证明页面能热更新,pnpm build 才能同时暴露 MDX 编译、静态路由、索引与部署配置问题。

在个人技术博客的技术选型中,静态站点生成(SSG)通常能带来较低的服务器成本与较好的访问体验。

Nextra 4 支持 Next.js App Router,允许直接将 app/posts/<slug>/page.mdx 映射为标准页面路由。本文梳理从 MDX 渲染、Pagefind 静态检索到 Docker 容器化打包的完整搭建流程。


博客架构拓扑

TEXT
app/posts/<slug>/page.mdx (MDX 文章源码)
  │
  ▼ Next.js 静态编译 (next build / output: 'export')
out/ 静态站点产物 (HTML + JS + CSS)
  │
  ├─► npx pagefind --site out ──► 生成 WebAssembly 离线全局搜索索引
  ├─► npx next-sitemap ────────► 生成 sitemap.xml 与 robots.txt
  │
  ▼ Docker 多阶段打包 (Node 构建 -> Nginx Alpine 静态服务)
输出仅 25MB 的高可用镜像 blog:sha-<commit>

关键工程配置实战

1. next.config.ts 配置

TS
import nextra from 'nextra';
 
const withNextra = nextra({
  // 启用静态图片优化与提取
  staticImage: true,
});
 
export default withNextra({
  // 关键:导出为纯静态 HTML/CSS 资产
  output: 'export',
  images: {
    unoptimized: true, // 静态导出需禁用服务端图片动态压缩
  },
});

2. MDX 自定义组件映射 (mdx-components.tsx)

在根目录下创建 mdx-components.tsx,统一拦截 Markdown 标签并赋予交互能力:

TSX
import type { MDXComponents } from 'mdx/types';
 
export function useMDXComponents(components: MDXComponents): MDXComponents {
  return {
    ...components,
    // 为代码块添加复制按钮与优雅样式
    pre: ({ children, ...props }) => (
      <pre className="relative overflow-x-auto rounded-xl bg-gray-900 p-4 text-sm" {...props}>
        {children}
      </pre>
    ),
  };
}

3. next-sitemap.config.cjs 自动化 SEO

JS
/** @type {import('next-sitemap').IConfig} */
module.exports = {
  siteUrl: process.env.NEXT_PUBLIC_SITE_URL || 'https://my-blog.com',
  generateRobotsTxt: true,
  output: 'export',
  sitemapSize: 5000,
  outDir: 'out',
};

生产级 Docker 多阶段构建 (Dockerfile)

为了确保博客能在任意服务器以极小体积、零环境依赖运行,采用 Multi-Stage Dockerfile:

DOCKERFILE
# 阶段一:依赖安装与构建
FROM node:20-alpine AS builder
RUN corepack enable && corepack prepare pnpm@latest --activate
WORKDIR /app
 
COPY package.json pnpm-lock.yaml ./
RUN pnpm install --frozen-lockfile
 
COPY . .
ARG NEXT_PUBLIC_SITE_URL
ENV NEXT_PUBLIC_SITE_URL=$NEXT_PUBLIC_SITE_URL
 
# 执行静态构建与索引生成
RUN pnpm build
 
# 阶段二:生产 Nginx 极简镜像
FROM nginx:alpine AS runner
WORKDIR /usr/share/nginx/html
 
# 仅拷贝构建产物
COPY --from=builder /app/out ./
COPY deploy/nginx.conf /etc/nginx/conf.d/default.conf
 
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

官方资料

工程经验小结

纯静态博客架构免除了服务端进程常驻的运维与安全负担。

但在配置 Next.js output: 'export' 时,所有依赖服务端的运行时特性(如动态服务端重定向、Cookie 读取、服务端 Header 处理)都无法生效,必须转由构建期脚本或 Nginx/CDN 边缘规则接管。

另外,每次新增文章或修改元数据后,应保证本地能跑通完整构建与 SEO 校验脚本(如 pnpm build 与 verify-seo.mjs),避免将损坏的路由或缺失的 Frontmatter 推送到生产环境。

评论