Next.js Pages Router (遺留系統與遷移指南)
在 Next.js 13 推出 App Router 之前,Pages Router 是 Next.js 的黃金標準。雖然新專案應優先使用 App Router,但在許多企業級專案中,Pages Router 依然佔有一席之地。
本篇旨在幫助你維護舊專案,並提供一條清晰的遷移路徑。
核心架構差異
| 特性 | Pages Router (pages/) | App Router (app/) |
|---|---|---|
| 路由定義 | 檔案系統即路由 (index.tsx) | 資料夾即路由 (page.tsx) |
| 渲染預設 | Client Side ( hydration ) | Server Components (預設) |
| 資料擷取 | getStaticProps / getServerSideProps | async/await 直接在組件內 |
| 佈局 (Layout) | _app.tsx (全域單一) | 巢狀 Layouts (layout.tsx) |
資料擷取函式 (Data Fetching Methods)
Pages Router 不支援在組件內直接 async/await,必須透過特定的 export function。
getStaticProps (SSG)
在 Build Time 執行,將 props 傳入頁面組件。
// pages/blog/[slug].tsx
export async function getStaticProps(context) {
const post = await db.post.findUnique({ where: { slug: context.params.slug } });
return {
props: { post },
revalidate: 60, // ISR: 每 60 秒重新生成
};
}
export async function getStaticPaths() {
// 定義哪些路徑要預先生成
return {
paths: [{ params: { slug: 'hello-world' } }],
fallback: 'blocking',
};
}
getServerSideProps (SSR)
在這個函式內的程式碼,每次請求都會執行。
// pages/profile.tsx
export async function getServerSideProps(context) {
const session = await getSession(context.req);
if (!session) {
return {
redirect: { destination: '/login', permanent: false },
};
}
return { props: { user: session.user } };
}
遷移對照表 (Migration Cheat Sheet)
如果你正在將專案從 Pages 遷移到 App Router,請參考以下對照:
A. 資料擷取 (Data Fetching)
舊 (Pages):
export async function getStaticProps() {
const data = await getData();
return { props: { data } };
}
export default function Page({ data }) { ... }
新 (App):
async function getData() { ... }
export default async function Page() {
const data = await getData();
return <div>...</div>;
}
B. 動態路徑 (Dynamic Paths)
- 舊:
getStaticPaths - 新:
generateStaticParams(注意:語法和回傳格式略有不同,只需回傳 params 陣列,不需包在paths物件裡)。
C. 路由 Hook (Router Hooks)
- 舊:
import { useRouter } from 'next/router' - 新:
import { useRouter } from 'next/navigation'(僅限 Client Component,用於導航)import { useSearchParams } from 'next/navigation'(讀取 Query Params)import { usePathname } from 'next/navigation'(讀取路徑)
共存策略 (Incremental Adoption)
Next.js 允許 pages/ 和 app/ 目錄同時存在。這意味著你不需要一次重寫整個網站。
- 新功能優先使用 App Router:新建立的頁面直接放在
app/下。 - 逐步搬移:一次挑選一個路由(例如
/about),將其從pages/about.tsx移至app/about/page.tsx。 - 解決衝突:如果同一個路徑同時存在於兩者,
app/目錄的優先權較高。
結語
Pages Router 是 Next.js 成功的基石,它的許設計模式(如檔案系統路由)至今仍被沿用。了解它的運作原理,不僅能幫助你維護舊程式碼,更能讓你深刻體會 App Router 架構演進的精妙之處。