自訂 Document

自訂 Document 可用來更新渲染 頁面 (Page) 時所使用的 <html><body> 標籤。

要覆寫預設的 Document,請建立 pages/_document 檔案,如下所示:

import { Html, Head, Main, NextScript } from 'next/document'

export default function Document() {
  return (
    <Html lang="en">
      <Head />
      <body>
        <Main />
        <NextScript />
      </body>
    </Html>
  )
}

須知事項:

  • _document 僅在伺服器端渲染,因此無法在此檔案中使用像是 onClick 這樣的事件處理器。
  • 頁面要正確渲染必須包含 <Html><Head /><Main /><NextScript /> 這些元件。

注意事項

  • _document 中使用的 <Head /> 元件與 next/head 不同。此處的 <Head /> 元件應僅用於所有頁面共用的 <head> 程式碼。對於其他情況(例如 <title> 標籤),建議在頁面或元件中使用 next/head
  • <Main /> 之外的 React 元件不會被瀏覽器初始化。請勿在此處添加應用程式邏輯或自訂 CSS(如 styled-jsx)。如果需要所有頁面共用的元件(如選單或工具列),請參閱 佈局 (Layouts)
  • Document 目前不支援 Next.js 的 資料獲取方法,例如 getStaticPropsgetServerSideProps

自訂 renderPage

自訂 renderPage 屬於進階用法,通常僅在需要支援伺服器端渲染的函式庫(如 CSS-in-JS)時使用。內建的 styled-jsx 支援不需要此設定。

我們不建議使用此模式。 相反地,可以考慮 逐步採用 App Router,它能更輕鬆地為頁面和佈局獲取資料。

import Document, {
  Html,
  Head,
  Main,
  NextScript,
  DocumentContext,
  DocumentInitialProps,
} from 'next/document'

class MyDocument extends Document {
  static async getInitialProps(
    ctx: DocumentContext
  ): Promise<DocumentInitialProps> {
    const originalRenderPage = ctx.renderPage

    // 同步執行 React 渲染邏輯
    ctx.renderPage = () =>
      originalRenderPage({
        // 適用於包裝整個 React 樹
        enhanceApp: (App) => App,
        // 適用於按頁面包裝
        enhanceComponent: (Component) => Component,
      })

    // 執行父級的 `getInitialProps`,現在它包含自訂的 `renderPage`
    const initialProps = await Document.getInitialProps(ctx)

    return initialProps
  }

  render() {
    return (
      <Html lang="en">
        <Head />
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    )
  }
}

export default MyDocument

須知事項:

  • _document 中的 getInitialProps 在客戶端轉換時不會被呼叫。
  • _documentctx 物件與 getInitialProps 接收到的相同,但額外增加了 renderPage 屬性。

On this page