跳到內容

動態路由

當你事先不知道確切的區段名稱,並想從動態資料建立路由時,你可以使用動態區段,這些區段會在請求時填入,或在建置時預先渲染

慣例

動態區段可以通過將資料夾名稱包在方括號中來建立:[folderName]。例如,[id][slug]

動態區段會作為 params 屬性傳遞給 layoutpageroutegenerateMetadata 函式。

範例

例如,一個部落格可以包含以下路由 app/blog/[slug]/page.js,其中 [slug] 是部落格文章的動態區段。

app/blog/[slug]/page.tsx
export default async function Page({
  params,
}: {
  params: Promise<{ slug: string }>
}) {
  const slug = (await params).slug
  return <div>My Post: {slug}</div>
}
路由範例 URLparams
app/blog/[slug]/page.js/blog/a{ slug: 'a' }
app/blog/[slug]/page.js/blog/b{ slug: 'b' }
app/blog/[slug]/page.js/blog/c{ slug: 'c' }

請參閱 generateStaticParams() 頁面,以了解如何為區段產生參數。

要知道

  • 由於 params 屬性是一個 Promise。你必須使用 async/await 或 React 的 use 函式來存取這些值。
    • 在版本 14 及更早版本中,params 是一個同步屬性。為了幫助向後相容性,你仍然可以在 Next.js 15 中同步存取它,但此行為在未來將會被棄用。
  • 動態區段等同於 pages 目錄中的 動態路由

產生靜態參數

generateStaticParams 函式可以與動態路由區段結合使用,以在建置時靜態產生路由,而不是在請求時按需產生。

app/blog/[slug]/page.tsx
export async function generateStaticParams() {
  const posts = await fetch('https://.../posts').then((res) => res.json())
 
  return posts.map((post) => ({
    slug: post.slug,
  }))
}

generateStaticParams 函式的主要優點是其智慧型資料檢索。如果在 generateStaticParams 函式中使用 fetch 請求抓取內容,則請求會自動記憶化。這表示在多個 generateStaticParams、版面配置和頁面中使用相同引數的 fetch 請求只會發出一次,從而縮短建置時間。

如果你是從 pages 目錄遷移,請使用遷移指南

有關更多資訊和進階使用案例,請參閱 generateStaticParams 伺服器函式文件

萬用字元區段

動態區段可以擴展為萬用字元後續區段,方法是在方括號內新增省略號 [...folderName]

例如,app/shop/[...slug]/page.js 將會匹配 /shop/clothes,也會匹配 /shop/clothes/tops/shop/clothes/tops/t-shirts 等等。

路由範例 URLparams
app/shop/[...slug]/page.js/shop/a{ slug: ['a'] }
app/shop/[...slug]/page.js/shop/a/b{ slug: ['a', 'b'] }
app/shop/[...slug]/page.js/shop/a/b/c{ slug: ['a', 'b', 'c'] }

選用性萬用字元區段

萬用字元區段可以通過將參數包含在雙方括號中來設為選用性[[...folderName]]

例如,app/shop/[[...slug]]/page.js會匹配 /shop,除了 /shop/clothes/shop/clothes/tops/shop/clothes/tops/t-shirts 之外。

萬用字元區段和選用性萬用字元區段之間的區別在於,對於選用性萬用字元區段,不帶參數的路由也會被匹配(在上面的範例中為 /shop)。

路由範例 URLparams
app/shop/[[...slug]]/page.js/shop{ slug: undefined }
app/shop/[[...slug]]/page.js/shop/a{ slug: ['a'] }
app/shop/[[...slug]]/page.js/shop/a/b{ slug: ['a', 'b'] }
app/shop/[[...slug]]/page.js/shop/a/b/c{ slug: ['a', 'b', 'c'] }

TypeScript

當使用 TypeScript 時,你可以根據你設定的路由區段為 params 新增類型。

app/blog/[slug]/page.tsx
export default async function Page({
  params,
}: {
  params: Promise<{ slug: string }>
}) {
  return <h1>My Page</h1>
}
路由params 類型定義
app/blog/[slug]/page.js{ slug: string }
app/shop/[...slug]/page.js{ slug: string[] }
app/shop/[[...slug]]/page.js{ slug?: string[] }
app/[categoryId]/[itemId]/page.js{ categoryId: string, itemId: string }

要知道:這可能會在未來由 TypeScript 外掛程式 自動完成。