跳到主內容

【Next.js】路由機制(動態)

在 Next.js 中,**Dynamic Routes(動態路由)**允許你根據 URL 中的參數來動態建立頁面,這對於像是部落格文章、使用者頁面、商品詳細頁等非常有用。


🗂️ 基本概念

在 Next.js 中,每個檔案都對應一個路由。當你在 app/pages/ 目錄中使用 方括號([param]) 定義檔案名稱時,就代表建立了一個動態路由。

例如:

pages/
  └── blog/
        └── [slug].tsx

這樣的結構可以對應:

  • /blog/hello-world

  • /blog/my-second-post

app/ 目錄中則會是:

app/
  └── blog/
        └── [slug]/
              └── page.tsx

💡 Dynamic Routes 實作(pages/)(舊版功能Next13 以前)

1️⃣ 建立檔案:pages/post/[id].tsx

import { useRouter } from 'next/router'

export default function Post() {
  const router = useRouter()
  const { id } = router.query

  return <h1>Post ID: {id}</h1>
}

訪問 /post/123 → 顯示 Post ID: 123


💡 Dynamic Routes 實作(app/

1️⃣ 建立檔案:app/post/[id]/page.tsx

interface PageProps {
  params: { id: string }
}

export default function Post({ params }: PageProps) {
  return <h1>Post ID: {params.id}</h1>
}

// { params }: PageProps
// { params } => 解構,取出物件的 params 屬性
// :PageProps typescript宣告型別
// 直接簡化成 { params }: { params: { id: string } }

🔁 多層動態路由

支援巢狀結構,例如:

app/
  └── user/
        └── [userId]/
              └── post/
                    └── [postId]/
                          └── page.tsx

訪問路徑 /user/1/post/10 對應的 params 為:

params: {
  userId: '1',
  postId: '10'
}

✅ Catch-all 路由(捕捉所有)

你可以使用 [...slug] 來捕捉多層級路徑:

  • pages/docs/app/products/[...slug].tsx 會匹配 /docs/products/a/docs/products/a/b/c

constinterface Docs = () =>PageProps {
  const router = useRouter()
  constparams: {
    slugslug?: string[];
  };
}

=export router.querydefault function ProductPage({ params }: PageProps) {
  return (
    <pdiv>Slug:
      <h1>Products Page</h1>
      <pre>{JSON.stringify(params.slug)}</ppre>
    </div>
  );
}

如果要可選,可用 [[...slug]] 表示非必要。


pages/ vs app/ 差異總覽

項目 pages/ 目錄(Pages Router) app/ 目錄(App Router)
路由方式 檔名對應 URL(傳統) 檔名+資料夾對應 URL(新式、模組化)
檔案命名 pages/index.tsx, pages/about.tsx app/page.tsx, app/about/page.tsx
動態路由 [id].tsx [id]/page.tsx
資料抓取 (Data Fetching) getStaticProps, getServerSideProps fetch + async component + generateStaticParams
頁面元件 function component (無 layout 管理) 支援 layout.tsx, error.tsx, loading.tsx
支援 RSC (React Server Component) ❌ 僅支援 CSR/SSR/SSG ✅ 原生支援 Server Components
Server Actions ❌ 不支援 ✅ 支援(可在伺服器端直接處理表單等邏輯)
Incremental Static Regeneration (ISR) ✅ 支援 ✅ 支援
適合對象 傳統 SSR/SSG 專案、快速上手 複雜應用、大型專案、Server-first 架構

📌 小結

類型 說明 範例
[param] 基本動態路由 /post/1[id].tsx
[...param] 捕捉多層路徑(Catch-all) /docs/a/b[...slug].tsx
[[...param]] 可選 catch-all(Optional) /docs or /docs/a

若你想看實際範例或搭配 getStaticPathsgenerateStaticParams 使用,也可以提出,我可以補上。需要嗎?