返回博客

Next.js 静态导出(output: 'export')完全指南

Next.js 静态导出(output: 'export')完全指南

2026年10月10日 — Next.js

发布于

2026年10月10日

阅读时长

4 分钟

分类

Next.js

标签

  • Next.js
  • Static Export
  • App Router
  • Hosting

(摘要)Next.js 静态导出在 App Router 中如何工作、有哪些限制,以及图片、动态路由、表单和重定向的解决方案。

静态导出的 Next.js 网站就是一个文件夹里的 HTML、CSS、JavaScript 和静态资源。你可以把它放到任何静态托管上——Cloudflare Pages、GitHub Pages、S3、Netlify 或一台 Nginx 服务器——不需要运行、维护或付费的 Node.js 服务器。这个网站就是这样构建的。

本指南介绍静态导出在 App Router 中的工作方式、你会失去什么,以及每个限制的绕过方法。

开启静态导出

从 Next.js 14 开始,next export 命令已被移除,静态导出改为配置项:

next.config.mjs
/** @type {import('next').NextConfig} */
const nextConfig = {
  output: 'export',
  // Optional: /about → /about/index.html instead of /about.html
  trailingSlash: true,
  images: { unoptimized: true },
}

export default nextConfig

现在 next build 会把网站输出到 out/ 目录。用任意静态服务器预览:

bash
npx serve out

可以用的功能

比很多人想象的多:

  • 服务端组件(Server Components)。 它们在构建时运行一次。获取数据、读取文件、调用 API——结果直接写进 HTML。
  • 客户端组件(Client Components)、hooks、context 以及所有客户端库。
  • 动态路由,前提是用 generateStaticParams 列出所有路径。
  • 只有 GET 的 Route Handlers,会生成静态文件(很适合 feed.json、sitemap.xml、robots.txt)。
  • Metadata API:标题、描述、Open Graph、canonical 链接。
  • 使用 <Link> 的客户端导航和预加载。

不能用的功能,以及替代方案

功能 失效原因 替代方案
默认图片优化 需要服务器 images.unoptimized: true、预先裁好尺寸,或自定义 loader(Cloudinary、imgix、Cloudflare Images)
没有 generateStaticParams 的动态路由 页面必须在构建时确定 列出所有参数,并设置 dynamicParams = false
cookies()、headers() 等请求时数据 运行时没有请求 在客户端读取,或把逻辑移到 API
Server Actions 需要服务器 POST 到无服务器函数(Workers、Lambda)
Middleware 需要服务器 托管平台层面的规则:_redirects、_headers、边缘函数
配置中的 redirects、rewrites、headers 由 Next 服务器执行 同上:在托管平台配置
ISR / revalidate 没有服务器来重新生成 内容变化时重新构建(Git 推送或 webhook)
内置 i18n 路由 Pages Router 的功能 使用语言路由段:app/[lang]/... 配合 generateStaticParams

正确处理动态路由

每个动态路由段都需要在构建时提供所有取值:

app/blog/[slug]/page.tsx
import { getAllPosts, getPost } from '@/lib/blog'
import { notFound } from 'next/navigation'

export const dynamicParams = false // unknown slugs are a 404, not a runtime render

export async function generateStaticParams() {
  const posts = await getAllPosts()
  return posts.map((post) => ({ slug: post.slug }))
}

export default async function Page({ params }: { params: Promise<{ slug: string }> }) {
  const { slug } = await params
  const post = await getPost(slug)
  if (!post) notFound()
  return <article dangerouslySetInnerHTML={{ __html: post.html }} />
}

注意:在 Next.js 15 中 params 是一个 Promise,需要 await。

一个坑:如果 generateStaticParams 返回空数组,构建会失败,因为这个路由不会生成任何页面。如果集合可能为空(比如刚建的博客),就返回一个占位参数,让它渲染 404。

图片

有三种合理的选择:

  1. unoptimized: true,自己导出合适尺寸的图片(WebP 或 AVIF,显示宽度的 1–2 倍)。只要你足够自律,这种方式简单又快。
  2. 自定义 loader,指向图片 CDN,按需返回不同尺寸:
image-loader.js
export default function loader({ src, width, quality }) {
  return `https://images.example.com/${src}?w=${width}&q=${quality || 75}`
}
next.config.mjs
const nextConfig = {
  output: 'export',
  images: { loader: 'custom', loaderFile: './image-loader.js' },
}
  1. 普通 <img>,配合 srcset、loading="lazy" 以及明确的 width/height,避免布局偏移。

表单和其他服务端功能

静态网站依然可以有表单、搜索和登录——只是服务端部分放在别处。常见做法是一个小型无服务器函数,页面通过 fetch 调用它。我把本站使用的方案写在了用 Cloudflare Workers 和 D1 搭建无服务器联系表单。

重定向和响应头

在托管平台配置。在 Cloudflare Pages 和 Netlify 上,public/ 里的 _redirects 文件会被复制到 out/:

public/_redirects
/old-page    /new-page    301
/blog/*      /journal/:splat    301

用 _headers 配置缓存和安全响应头:

public/_headers
/_next/static/*
  Cache-Control: public, max-age=31536000, immutable

没有服务器如何更新内容

因为没有 ISR,内容变化需要重新构建。这其实没有听起来那么麻烦:把托管平台连接到 Git 仓库,每次推送都会在一两分钟内自动构建和部署。如果内容放在 CMS 里,把 CMS 的 webhook 指向托管平台的部署钩子即可。对博客来说,把文章作为 Markdown 放在仓库里是最简单的方案——见不用 CMS,在 Next.js 中搭建 Markdown 博客。

什么时候不适合静态导出

  • 依赖登录用户、需要在服务端渲染的页面。
  • 成千上万、每几分钟就变化的页面(构建时间随页面数增长)。
  • 确实需要请求时渲染的场景,比如个性化定价。

对于官网、作品集、文档、博客和落地页,静态导出通常是最快、最便宜也最稳定的方案。

检查清单

  • next.config 中设置 output: 'export'
  • 每个动态路由都有 generateStaticParams 和 dynamicParams = false
  • 图片已处理(unoptimized、自定义 loader 或 <img>)
  • 没有使用 cookies()、headers()、Server Actions 或 middleware
  • 重定向和响应头在托管平台配置
  • 部署由 Git 推送或 CMS webhook 触发
  • 首次部署前在本地预览过 out/

下一步:确保搜索引擎能理解你导出的页面——Next.js App Router 技术 SEO 清单。

订阅

通过邮件接收新文章

有新文章时发一封简短的邮件。不发垃圾邮件,随时可以退订。

Next.js App Router 技术 SEO 实用清单
Next.js App Router 技术 SEO 实用清单
下一篇 →