getStaticProps
匯出名為 getStaticProps 的函式將使用該函式返回的 props 在構建時預渲染頁面
import type { InferGetStaticPropsType, GetStaticProps } from 'next'
type Repo = {
name: string
stargazers_count: number
}
export const getStaticProps = (async (context) => {
const res = await fetch('https://api.github.com/repos/vercel/next.js')
const repo = await res.json()
return { props: { repo } }
}) satisfies GetStaticProps<{
repo: Repo
}>
export default function Page({
repo,
}: InferGetStaticPropsType<typeof getStaticProps>) {
return repo.stargazers_count
}你可以在頂層作用域中匯入模組以在 getStaticProps 中使用。所使用的匯入將不會為客戶端打包。這意味著你可以在 getStaticProps 中直接編寫伺服器端程式碼,包括從資料庫獲取資料。
Context 引數
context 引數是一個包含以下鍵的物件
| 名稱 | 描述 |
|---|---|
params | 包含使用動態路由的頁面的路由引數。例如,如果頁面名稱是 [id].js,那麼 params 將看起來像 { id: ... }。你應該將其與 getStaticPaths 一起使用,我們稍後會解釋。 |
preview | (已廢棄,改用 draftMode) 如果頁面處於預覽模式,則 preview 為 true,否則為 false。 |
previewData | (已廢棄,改用 draftMode) 由 setPreviewData 設定的預覽資料。 |
draftMode | 如果頁面處於草稿模式,則 draftMode 為 true,否則為 false。 |
locale | 包含活動區域設定(如果已啟用)。 |
locales | 包含所有支援的區域設定(如果已啟用)。 |
defaultLocale | 包含配置的預設區域設定(如果已啟用)。 |
revalidateReason | 提供函式被呼叫的原因。可以是以下之一:“build”(在構建時執行)、“stale”(重新驗證週期過期,或在開發模式下執行)、“on-demand”(透過按需重新驗證觸發) |
getStaticProps 返回值
getStaticProps 函式應返回一個物件,其中包含 props、redirect 或 notFound,後跟一個可選的 revalidate 屬性。
props
props 物件是鍵值對,其中每個值都由頁面元件接收。它應該是一個可序列化物件,以便任何傳遞的 props 都可以透過 JSON.stringify 序列化。
export async function getStaticProps(context) {
return {
props: { message: `Next.js is awesome` }, // will be passed to the page component as props
}
}`revalidate`
revalidate 屬性是頁面重新生成可以發生的秒數(預設為 false 或不重新驗證)。
// This function gets called at build time on server-side.
// It may be called again, on a serverless function, if
// revalidation is enabled and a new request comes in
export async function getStaticProps() {
const res = await fetch('https://.../posts')
const posts = await res.json()
return {
props: {
posts,
},
// Next.js will attempt to re-generate the page:
// - When a request comes in
// - At most once every 10 seconds
revalidate: 10, // In seconds
}
}瞭解更多關於增量靜態生成。
利用 ISR 的頁面的快取狀態可以透過讀取 x-nextjs-cache 響應頭的值來確定。可能的值如下:
MISS- 路徑不在快取中(最多發生一次,在首次訪問時)STALE- 路徑在快取中但超過了重新驗證時間,因此它將在後臺更新HIT- 路徑在快取中且未超過重新驗證時間
notFound
notFound 布林值允許頁面返回 404 狀態和404 頁面。如果設定 notFound: true,即使之前成功生成了頁面,該頁面也會返回 404。這旨在支援使用者生成的內容被其作者刪除等用例。請注意,notFound 遵循此處所述的相同 revalidate 行為。
export async function getStaticProps(context) {
const res = await fetch(`https://.../data`)
const data = await res.json()
if (!data) {
return {
notFound: true,
}
}
return {
props: { data }, // will be passed to the page component as props
}
}須知:對於
fallback: false模式,不需要notFound,因為只有getStaticPaths返回的路徑才會被預渲染。
redirect
redirect 物件允許重定向到內部或外部資源。它應該匹配 { destination: string, permanent: boolean } 的格式。
在某些罕見情況下,你可能需要為舊的 HTTP 客戶端分配自定義狀態碼才能正確重定向。在這些情況下,你可以使用 statusCode 屬性而不是 permanent 屬性,但不能同時使用兩者。你還可以像在 next.config.js 中重定向一樣設定 basePath: false。
export async function getStaticProps(context) {
const res = await fetch(`https://...`)
const data = await res.json()
if (!data) {
return {
redirect: {
destination: '/',
permanent: false,
// statusCode: 301
},
}
}
return {
props: { data }, // will be passed to the page component as props
}
}如果重定向在構建時已知,則應將其新增到next.config.js中。
讀取檔案:使用 process.cwd()
可以直接從檔案系統中在 getStaticProps 中讀取檔案。
為此,你必須獲取檔案的完整路徑。
由於 Next.js 將你的程式碼編譯到單獨的目錄中,因此你不能使用 __dirname,因為它返回的路徑將與 Pages Router 不同。
相反,你可以使用 process.cwd(),它為你提供了 Next.js 正在執行的目錄。
import { promises as fs } from 'fs'
import path from 'path'
// posts will be populated at build time by getStaticProps()
function Blog({ posts }) {
return (
<ul>
{posts.map((post) => (
<li>
<h3>{post.filename}</h3>
<p>{post.content}</p>
</li>
))}
</ul>
)
}
// This function gets called at build time on server-side.
// It won't be called on client-side, so you can even do
// direct database queries.
export async function getStaticProps() {
const postsDirectory = path.join(process.cwd(), 'posts')
const filenames = await fs.readdir(postsDirectory)
const posts = filenames.map(async (filename) => {
const filePath = path.join(postsDirectory, filename)
const fileContents = await fs.readFile(filePath, 'utf8')
// Generally you would parse/transform the contents
// For example you can transform markdown to HTML here
return {
filename,
content: fileContents,
}
})
// By returning { props: { posts } }, the Blog component
// will receive `posts` as a prop at build time
return {
props: {
posts: await Promise.all(posts),
},
}
}
export default Blog版本歷史
| 版本 | 更改 |
|---|---|
v13.4.0 | App Router 現已穩定,資料獲取已簡化 |
v12.2.0 | 按需增量靜態生成已穩定。 |
v12.1.0 | 按需增量靜態生成已新增(beta)。 |
v10.0.0 | 添加了 locale、locales、defaultLocale 和 notFound 選項。 |
v10.0.0 | 添加了 fallback: 'blocking' 返回選項。 |
v9.5.0 | 穩定的增量靜態生成 |
v9.3.0 | 引入了 getStaticProps。 |
這有幫助嗎?