動態路由

當您無法預先知道確切的路由區段名稱,並希望從動態資料建立路由時,可以使用在請求時填入或預先渲染的動態區段。

慣例

動態區段可透過將資料夾名稱用方括號包裹來建立:[folderName]。例如 [id][slug]

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

範例

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

export default function Page({ params }: { params: { slug: string } }) {
  return <div>My Post: {params.slug}</div>
}
路由範例網址params
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() 頁面以了解如何為區段產生參數。

須知:動態區段等同於 pages 目錄中的動態路由

產生靜態參數

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

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 等。

路由範例網址params
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/clothes/shop/clothes/tops/shop/clothes/tops/t-shirts 外,還會匹配 /shop

萬用可選萬用區段的區別在於,可選區段也會匹配不帶參數的路由(如上例中的 /shop)。

路由範例網址params
app/shop/[[...slug]]/page.js/shop{}
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 添加型別。

export default function Page({ params }: { params: { 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 外掛自動完成。

On this page