静态导出 SSG

2026年9月6日

output: "export" 会在构建时把能确定的页面收成 HTML / CSS / JS,丢到 Nginx、对象存储、任意静态托管即可。官网、博客、文档这类内容变化慢的站最合适。本站笔记页也是按静态思路出的。


打开静态导出

import type { NextConfig } from "next";

const nextConfig: NextConfig = {
  output: "export",
  distDir: "dist",
};

export default nextConfig;
ts

distDir 默认是 out,改成 dist 只是换目录名。然后:

pnpm build
npx http-server dist -p 3000
bash

trailingSlash

导出后常见坑:链接写的是 /about,磁盘上却是 about.html。静态服务器按目录找 about/index.html 时,点 <a> 会 404。

const nextConfig: NextConfig = {
  output: "export",
  distDir: "dist",
  trailingSlash: true,
};
ts

打开后生成 /about/index.html,访问 /about/ 就能对上。Link 和站点内跳转一起改完再测一遍。


动态路由

静态导出必须在构建期列出所有参数,靠 generateStaticParams

export async function generateStaticParams() {
  return [{ id: "1" }, { id: "2" }];
}

export default async function Post({
  params,
}: {
  params: Promise<{ id: string }>;
}) {
  const { id } = await params;
  return <h1>Post {id}</h1>;
}
tsx

列表可以从接口拉。没列出来的 id 不会有 HTML;dynamicParams: true 这种「请求时再生成」在纯静态里不可用。


图片

默认的 Image 优化要跑 Node 服务。开了 export 会报:默认 loader 和静态导出不兼容。三条路:

  1. 去掉 output: "export",用 next start
  2. images: { unoptimized: true },原图直出
  3. 自定义 loader,把缩放交给图床 / CDN
images: {
  loader: "custom",
  loaderFile: "./image-loader.ts",
}
ts
export default function imageLoader({
  src,
  width,
  quality,
}: {
  src: string;
  width: number;
  quality?: number;
}) {
  const q = quality ?? 75;
  return `https://cdn.example.com${src}?w=${width}&q=${q}`;
}
ts

页面里 src 写图床路径即可。本地 public 图用 unoptimized 更省事。


静态导出用不了的能力

这些都依赖运行中的 Next 服务器,导出后没有:

  • 没写 generateStaticParams 的动态段
  • Request 的 Route Handler
  • cookies / Draft Mode
  • rewrites / redirects / headers(配置级的那些)
  • Proxy
  • ISR
  • 默认 Image 优化
  • Server Actions
  • 拦截路由

表单提交、按用户个性化、实时数据,别走纯静态。需要这些时用 Node / Vercel,或把接口拆到别的服务。

下一篇:MDX,静态站里写文档最常用的格式。


参考文档