跳至內容

動態路由

當您事先不知道確切的區段名稱,並且想要根據動態資料建立路由時,您可以使用在請求時填入的「動態區段」,或是在建置時預先渲染

慣例

您可以將資料夾名稱用方括號括起來,以建立動態區段:`[資料夾名稱]`。例如,`[id]` 或 `[slug]`。

動態區段會以 `params` 屬性傳遞給 `layout``page``route``generateMetadata` 函式。

範例
app/blog/[slug]/page.tsx
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` 目錄中的 動態路由

產生靜態參數 動態路由區段 結合使用,以便在建構時**靜態產生**路由,而不是在請求時按需產生。

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` 函式的主要優點是其智慧的資料擷取方式。如果使用 `fetch` 請求在 `generateStaticParams` 函式中擷取內容,則請求會自動記憶。這表示在多個 `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{ 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
app/blog/[slug]/page.tsx
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 插件 自動完成。

後續步驟

欲了解更多後續操作資訊,我們建議您參考以下章節