Intro
Next.js 是一個開源的 React 全端框架,後端基於 Node.js。它支援多種渲染方式 (Rendering),包括伺服器端渲染 (SSR)、靜態站點生成 (SSG) 以及用於客戶端渲染 (CSR) 的 React 原生渲染模式。
安裝 Next.js
-
Node.js 安裝指南
Next.js 需要依賴 Node.js,以下 Next.js 官網安裝指南會說明欲安裝版本對應的 Node.js 最低需求版本。 -
How to set up a new Next.js project - Next.js
目前無論選擇 App Router 或是 Page Router,皆為安裝同一包 Next.js source
路由器選擇 - App / Page Router
從 version 13 (2022) 開始,Next.js 引入新的 App Router,與舊版 Page Router 同時並存。
- 使用方式:
- App Router 會解析
/app
資料夾內的路由。 - Page Router 則繼續解析
/pages
資料夾內的路由。
- App Router 會解析
- 判定方式:
- 兩者會同時執行,分別解析其指定的資料夾。
- 如果兩者路徑發生衝突,Next.js 會直接回報錯誤,無法同時存在相同的路由。
- 資料夾結構差異:
- App Router:
基於文件夾層結構 (File-based Routing) 設計,每個路徑由資料夾內的 page.js (或 .tsx) 文件定義。(底線_
路徑對應需以%5F
命名資料夾)
支援Server Components,可透過 loading.js、error.js 等文件定義狀態處理。 - Page Router:
傳統的文件為基礎 (File-based Routing) 設計,每個路由由一個 .js (或 .tsx) 文件表示。主要用於Client Components,並透過 getStaticProps、getServerSideProps 等函數實現資料獲取。
- App Router:
特性 | App Router (新) | Page Router (舊) |
---|---|---|
資料夾結構 | /app 資料夾 |
/pages 資料夾 |
元件模型 | 預設使用 React Server Components (RSC) | 僅支援 React Client Components |
路由方式 | 文件式路由 (File-based Routing) | 同樣為 文件式路由 |
Layout 支援 | 內建 Layout, 可跨路由共享 | 需要手動在每頁引入 Layout |
渲染模式 | 支援 SSR、SSG、ISR、CSR | 支援 SSR、SSG、ISR、CSR |
動態路由 | 支援動態與分段路由 (Segment Routing) | 只支援傳統動態路由 |
Loading 狀態 | 內建 loading.js ,自動管理狀態 |
需手動在元件內處理 |
API 路由 | 使用 /app/api |
使用 /pages/api |
SEO 處理 | 使用 metadata 檔案設定 |
需使用 Head 元件手動設定 |
靜態資源 (Assets) | 可從 /public 資料夾訪問 |
相同使用 /public |
Deploying
Static Export
Next.js 官網 - Static Exports 提供了一個根目錄 host 的通用場景,並對 /blog/
子目錄設定 rewrite 模擬 Clean URL 效果
優化 - Clean URL
若要達到全目錄 Clean URL:
- nextConfig
trailingSlash
: 主要透過每頁轉成資料夾形式達到 Clean URL,out 產出結構會類似 App Router 結構
(e.g.app/about/page.tsx
=>out/about/index.html
) - 基於
trailingSlash
在網址隱藏各目錄下的 index.html & index.txt: 可以透過 Nginx 設定比對轉導:location / { # Redirect requests ending with index.html or index.txt under the directory if ($request_uri ~ ^(/.*)index\.(html|txt)$) { return 302 $1; } try_files $uri $uri.html $uri/ =404; }
在子目錄建置網站
若要在子目錄(sub-directory)下建置靜態網站,就會需要使用 nextConfig basePath
設定:
const nextConfig = {
output: 'export', // Exports the app as static HTML files
trailingSlash: true, // Adds a trailing slash to the end of each route (e.g., /about/)
basePath: '/nextjs/out', // Your desired path prefix
}
然而如 Next.js 官網 所述,Image 不支援自動載入 basePath
。較好的解決方式是從 next.config.js
import basePath
來定義 Image src
:
import { basePath } from '../next.config';
<Image src={${basePath}/next.svg
}/>
Nginx location 設定 (子目錄路徑得 hardcore 重複設定):
# Apply the rewrite for /nextjs/out
location /nextjs/out {
# Redirect requests ending with index.html or index.txt to the directory
if ($request_uri ~ ^/nextjs/out(/.*)index\.(html|txt)$) {
return 302 /nextjs/out$1;
}
# Try to serve files; if not found, return 404
try_files $uri $uri/ =404;
# Define the custom 404 error page
error_page 404 /nextjs/out/404.html;
}