generateStaticParams
generateStaticParams
函式可以與動態路由區段結合使用,以便在建置時靜態產生路由,而不是在請求時按需產生。
// Return a list of `params` to populate the [slug] dynamic segment
export async function generateStaticParams() {
const posts = await fetch('https://.../posts').then((res) => res.json())
return posts.map((post) => ({
slug: post.slug,
}))
}
// Multiple versions of this page will be statically generated
// using the `params` returned by `generateStaticParams`
export default async function Page({ params }) {
const { slug } = await params
// ...
}
注意事項:
- 您可以使用
dynamicParams
區段設定選項來控制當存取未透過generateStaticParams
產生的動態區段時會發生什麼情況。- 您必須從
generateStaticParams
回傳一個空陣列或使用export const dynamic = 'force-static'
才能在執行時重新驗證 (ISR) 路徑。- 在
next dev
開發模式中,當您導覽至某個路由時,會呼叫generateStaticParams
函式。- 在
next build
建置過程中,generateStaticParams
會在對應的佈局或頁面產生之前執行。- 在重新驗證 (ISR) 期間,不會再次呼叫
generateStaticParams
。generateStaticParams
取代了 Pages Router 中的getStaticPaths
函式。
參數
options.params
(選用)
如果路由中的多個動態區段使用 generateStaticParams
,則子 generateStaticParams
函式會針對父函式產生的每一組 params
執行一次。
params
物件包含來自父 generateStaticParams
的已填入 params
,可用於產生子區段中的 params
。
回傳值
generateStaticParams
應該回傳一個物件陣列,其中每個物件代表單一路由的已填入動態區段。
- 物件中的每個屬性都是要填入路由的動態區段。
- 屬性名稱是區段的名稱,而屬性值是該區段應該填入的值。
路由範例 | generateStaticParams 回傳類型 |
---|---|
/product/[id] | { id: string }[] |
/products/[category]/[product] | { category: string, product: string }[] |
/products/[...slug] | { slug: string[] }[] |
單一動態區段
export function generateStaticParams() {
return [{ id: '1' }, { id: '2' }, { id: '3' }]
}
// Three versions of this page will be statically generated
// using the `params` returned by `generateStaticParams`
// - /product/1
// - /product/2
// - /product/3
export default async function Page({ params }: { params: { id: string } }) {
const { id } = await params
// ...
}
多個動態區段
全方位動態區段
export function generateStaticParams() {
return [{ slug: ['a', '1'] }, { slug: ['b', '2'] }, { slug: ['c', '3'] }]
}
// Three versions of this page will be statically generated
// using the `params` returned by `generateStaticParams`
// - /product/a/1
// - /product/b/2
// - /product/c/3
export default async function Page({ params }: { params: { slug: string[] } }) {
const { slug } = await params
// ...
}
範例 靜態渲染
建置時渲染所有路徑
要在建置時靜態渲染所有路徑,請將完整路徑清單提供給 generateStaticParams
app/blog/[slug]/page.tsxexport async function generateStaticParams() {
const posts = await fetch('https://.../posts').then((res) => res.json())
return posts.map((post) => ({
slug: post.slug,
}))
}
建置時渲染部分路徑
要在建置時靜態渲染部分路徑,並在執行階段第一次訪問時渲染其餘路徑,請回傳部分路徑清單。
app/blog/[slug]/page.tsxexport async function generateStaticParams() {
const posts = await fetch('https://.../posts').then((res) => res.json())
// Render the first 10 posts at build time
return posts.slice(0, 10).map((post) => ({
slug: post.slug,
}))
}
然後,透過使用 dynamicParams
區段設定選項,您可以控制在訪問未透過 generateStaticParams
產生的動態區段時會發生什麼情況。
app/blog/[slug]/page.js// All posts besides the top 10 will be a 404
export const dynamicParams = false
export async function generateStaticParams() {
const posts = await fetch('https://.../posts').then((res) => res.json())
const topPosts = posts.slice(0, 10)
return topPosts.map((post) => ({
slug: post.slug,
}))
}
執行階段渲染所有路徑
要在第一次訪問時靜態渲染所有路徑,請回傳一個空陣列(建置時不會渲染任何路徑)或使用 export const dynamic = 'force-static'
app/blog/[slug]/page.jsexport async function generateStaticParams() {
return []
}
注意事項:您必須一律從 generateStaticParams
回傳一個陣列,即使它是空的。否則,路由將會動態渲染。
app/changelog/[slug]/page.jsexport const dynamic = 'force-static'
停用未指定路徑的渲染
為了防止未指定的路由路徑在運行時被靜態渲染,請在路由區段中加入 export const dynamicParams = false
選項。當使用此設定選項時,只有 generateStaticParams
提供的路徑才會被提供服務,而未指定的路由將會回傳 404 錯誤,或是匹配到全域捕捉路由(例如 全域捕捉路由 的情況)。
路由中的多個動態區段
您可以為目前佈局或頁面上方的動態區段產生參數,但**不能在其下方**。例如,給定 app/products/[category]/[product]
路由
app/products/[category]/[product]/page.js
可以為 [category]
和 [product]
**兩者** 產生參數。
app/products/[category]/layout.js
**只能** 為 [category]
產生參數。
有兩種方法可以為具有多個動態區段的路由產生參數
由下而上產生參數 app/products/[category]/[product]/page.tsx// Generate segments for both [category] and [product]
export async function generateStaticParams() {
const products = await fetch('https://.../products').then((res) => res.json())
return products.map((product) => ({
category: product.category.slug,
product: product.id,
}))
}
export default function Page({
params,
}: {
params: { category: string; product: string }
}) {
// ...
}
建置時渲染所有路徑
要在建置時靜態渲染所有路徑,請將完整路徑清單提供給 generateStaticParams
export async function generateStaticParams() {
const posts = await fetch('https://.../posts').then((res) => res.json())
return posts.map((post) => ({
slug: post.slug,
}))
}
建置時渲染部分路徑
要在建置時靜態渲染部分路徑,並在執行階段第一次訪問時渲染其餘路徑,請回傳部分路徑清單。
export async function generateStaticParams() {
const posts = await fetch('https://.../posts').then((res) => res.json())
// Render the first 10 posts at build time
return posts.slice(0, 10).map((post) => ({
slug: post.slug,
}))
}
然後,透過使用 dynamicParams
區段設定選項,您可以控制在訪問未透過 generateStaticParams
產生的動態區段時會發生什麼情況。
// All posts besides the top 10 will be a 404
export const dynamicParams = false
export async function generateStaticParams() {
const posts = await fetch('https://.../posts').then((res) => res.json())
const topPosts = posts.slice(0, 10)
return topPosts.map((post) => ({
slug: post.slug,
}))
}
執行階段渲染所有路徑
要在第一次訪問時靜態渲染所有路徑,請回傳一個空陣列(建置時不會渲染任何路徑)或使用 export const dynamic = 'force-static'
export async function generateStaticParams() {
return []
}
注意事項:您必須一律從
generateStaticParams
回傳一個陣列,即使它是空的。否則,路由將會動態渲染。
export const dynamic = 'force-static'
停用未指定路徑的渲染
為了防止未指定的路由路徑在運行時被靜態渲染,請在路由區段中加入 export const dynamicParams = false
選項。當使用此設定選項時,只有 generateStaticParams
提供的路徑才會被提供服務,而未指定的路由將會回傳 404 錯誤,或是匹配到全域捕捉路由(例如 全域捕捉路由 的情況)。
路由中的多個動態區段
您可以為目前佈局或頁面上方的動態區段產生參數,但**不能在其下方**。例如,給定 app/products/[category]/[product]
路由
app/products/[category]/[product]/page.js
可以為[category]
和[product]
**兩者** 產生參數。app/products/[category]/layout.js
**只能** 為[category]
產生參數。
有兩種方法可以為具有多個動態區段的路由產生參數
由下而上產生參數 app/products/[category]/[product]/page.tsx// Generate segments for both [category] and [product]
export async function generateStaticParams() {
const products = await fetch('https://.../products').then((res) => res.json())
return products.map((product) => ({
category: product.category.slug,
product: product.id,
}))
}
export default function Page({
params,
}: {
params: { category: string; product: string }
}) {
// ...
}
// Generate segments for both [category] and [product]
export async function generateStaticParams() {
const products = await fetch('https://.../products').then((res) => res.json())
return products.map((product) => ({
category: product.category.slug,
product: product.id,
}))
}
export default function Page({
params,
}: {
params: { category: string; product: string }
}) {
// ...
}