返回部落格

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 清單。

電子報

用 Email 訂閱新文章

有新文章時寄一封簡短的信給你。不發垃圾信,隨時可以取消訂閱。

Next.js App Router 技術 SEO 實用清單
Next.js App Router 技術 SEO 實用清單
下一篇