UGA Boxxx

つぶやきの延長のつもりで、知ったこと思ったこと書いてます

【Next.js】_app.jsと_document.js

Next.jsのサンプルコードにある_app.js_document.jsが何かを調査した

_app.js

nextjs.org

Next.jsは、Appコンポーネントを使用してページを初期化する

これをオーバーライドして、ページの初期化を制御する場合に_app.jsを使う

例えば

  • ページ変更間のレイアウトの永続化
  • ページをナビゲートするときの状態の保持
  • componentDidCatchを使用したカスタムエラー処理
  • ページに追加データを挿入する
  • グローバルCSSを追加する

Appを上書きする場合は、./pages/_app.jsを作成する

// import App from 'next/app'

function MyApp({ Component, pageProps }) {
  return <Component {...pageProps} />
}

// Only uncomment this method if you have blocking data requirements for
// every single page in your application. This disables the ability to
// perform automatic static optimization, causing every page in your app to
// be server-side rendered.
//
// MyApp.getInitialProps = async (appContext) => {
//   // calls page's `getInitialProps` and fills `appProps.pageProps`
//   const appProps = await App.getInitialProps(appContext);
//
//   return { ...appProps }
// }

export default MyApp

getInitialPropsを利用できるがgetStaticPropsgetServerSidePropsはサポートしていない

_document.js

nextjs.org

<html><body>タグを拡張するために使用される

デフォルトをオーバーライドするには、ファイル./pages/_document.jsを作成し、以下に示すようにDocumentクラスを拡張する

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

class MyDocument extends Document {
  static async getInitialProps(ctx) {
    const initialProps = await Document.getInitialProps(ctx)
    return { ...initialProps }
  }

  render() {
    return (
      <Html>
        <Head />
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    )
  }
}

export default MyDocument

このとき

  • サーバーサイドでレンダリングされるため、クライアントサイドの処理を書けない(onClickなど)
  • DocumentgetInitialPropsは、クライアントサイドの遷移中には呼び出されず、ページが静的に最適化されている場合にも呼び出されれない
  • getInitialPropsを利用できるがgetStaticPropsgetServerSidePropsはサポートしていない

他参考

https://qiita.com/tetsutaroendo/items/c7171286137d963cdecf