跳至內容

getStaticProps

如果您從頁面匯出名為 getStaticProps (靜態網站生成) 的函式,Next.js 將在建置時使用 getStaticProps 返回的屬性預先渲染此頁面。

pages/index.tsx
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
}

請注意,無論渲染類型為何,任何 props 都會傳遞給頁面組件,並且可以在客戶端初始 HTML 中檢視。這是為了允許頁面正確地水合(hydrate)。請確保您不要在 props 中傳遞任何不應在客戶端可用的敏感資訊。

getStaticProps API 參考涵蓋了所有可以與 getStaticProps 一起使用的參數和屬性。

我應該在什麼時候使用 getStaticProps?

您應該在以下情況下使用 getStaticProps

  • 渲染頁面所需的資料在使用者請求之前,於建置時即可取得。
  • 資料來自無頭 CMS(Headless CMS)。
  • 頁面必須預先渲染(為了 SEO)並且速度非常快 — getStaticProps 會產生 HTMLJSON 檔案,兩者都可以由 CDN 快取以提升效能。
  • 資料可以公開快取(非使用者特定)。在某些特定情況下,可以使用中間件(Middleware)重寫路徑來繞過此條件。

getStaticProps 何時運行 這個工具驗證 getStaticProps 內的程式碼已從客戶端套件中移除。

  • getStaticProps 總是在 next build 期間運行。
  • 使用 fallback: true 時,getStaticProps 會在背景運行。
  • 使用 fallback: blocking 時,getStaticProps 會在初始渲染之前被呼叫。
  • 使用 revalidate 時,getStaticProps 會在背景運行。
  • 使用 revalidate() 時,getStaticProps 會根據需求在背景運行。

當與 增量靜態再生 結合使用時,getStaticProps 會在背景執行,同時重新驗證過時的頁面,並將新的頁面提供給瀏覽器。

由於 getStaticProps 產生的是靜態 HTML,因此它無法存取傳入的請求(例如查詢參數或 HTTP 標頭)。如果您需要在頁面中存取請求,請考慮除了 getStaticProps 之外,再使用 中間件

使用 getStaticProps 從 CMS 提取數據

以下範例說明如何從 CMS 提取部落格文章列表。

pages/blog.tsx
// posts will be populated at build time by getStaticProps()
export default function Blog({ posts }) {
  return (
    <ul>
      {posts.map((post) => (
        <li>{post.title}</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() {
  // Call an external API endpoint to get posts.
  // You can use any data fetching library
  const res = await fetch('https://.../posts')
  const posts = await res.json()
 
  // By returning { props: { posts } }, the Blog component
  // will receive `posts` as a prop at build time
  return {
    props: {
      posts,
    },
  }
}

getStaticProps API 參考涵蓋了所有可以與 getStaticProps 一起使用的參數和屬性。

直接編寫伺服器端程式碼

由於 getStaticProps 僅在伺服器端運行,因此它永遠不會在客戶端運行。它甚至不會包含在瀏覽器的 JS 套件中,因此您可以直接編寫資料庫查詢,而不會將它們發送到瀏覽器。

這表示您可以直接在 getStaticProps 中編寫伺服器端程式碼,而不是從 getStaticProps 提取**API 路由**(它本身會從外部來源提取數據)。

以下列範例為例。API 路由用於從 CMS 提取一些數據。然後,該 API 路由會直接從 getStaticProps 呼叫。這會產生額外的呼叫,從而降低效能。您可以使用 lib/ 目錄共用用於從 CMS 提取數據的邏輯。然後,它可以與 getStaticProps 共用。

lib/load-posts.js
// The following function is shared
// with getStaticProps and API routes
// from a `lib/` directory
export async function loadPosts() {
  // Call an external API endpoint to get posts
  const res = await fetch('https://.../posts/')
  const data = await res.json()
 
  return data
}
pages/blog.js
// pages/blog.js
import { loadPosts } from '../lib/load-posts'
 
// This function runs only on the server side
export async function getStaticProps() {
  // Instead of fetching your `/api` route you can call the same
  // function directly in `getStaticProps`
  const posts = await loadPosts()
 
  // Props returned will be passed to the page component
  return { props: { posts } }
}

或者,如果您**不**使用 API 路由來提取數據,則可以在 getStaticProps 中直接使用 fetch() API 來提取數據。

要驗證 Next.js 從客戶端套件中刪除了哪些內容,您可以使用 next-code-elimination 工具.

靜態生成 HTML 和 JSON next/linknext/router 進行客戶端路由。當您導覽至使用 getStaticProps 預先渲染的頁面時,Next.js 會擷取此 JSON 檔案(在建置時預先計算)並將其用作頁面組件的屬性。這表示客戶端頁面轉換將**不會**呼叫 getStaticProps,因為只會使用匯出的 JSON。

使用增量靜態生成時,getStaticProps 將在背景執行以產生客戶端導覽所需的 JSON。您可能會看到針對同一頁面發出多個請求的形式,但這是預期的,並且不會影響最終使用者的效能。

在哪裡可以使用 getStaticProps

getStaticProps 只能從**頁面**匯出。您**不能**從非頁面檔案、_app_document_error 匯出它。

此限制的原因之一是 React 需要在渲染頁面前取得所有必要的資料。

此外,您必須將 getStaticProps 作為獨立函式匯出 — 如果您將 getStaticProps 作為頁面組件的屬性新增,它將**無法**正常運作。

**注意事項**: 如果您建立了自訂應用程式,請確保您將 pageProps 傳遞給頁面組件,如連結文件中所示,否則屬性將會是空的。

在開發環境中的每個請求上執行

在開發環境 (next dev) 中,getStaticProps 將在每個請求上被呼叫。

預覽模式

您可以使用預覽模式暫時略過靜態生成,並在**請求時**而不是建置時渲染頁面。例如,您可能正在使用無頭 CMS,並希望在發佈草稿之前預覽它們。