今回は、Next.jsで全体の設定ができる_document.js(tsx) と_app.js(tsx) について解説してききます✍️
_document.js(.tsx)
Next.jsのPageコンポーネントはデフォルトでは<html>・<body>タグの定義を行いますが、それらを拡張したい場合は _documet.js(tsx) を作成し、その中で Document コンポーネントを継承したクラスを実装しましょう。
class SampleDocument extends Document {
static async getInitialProps(ctx) {
const initialProps = await Document.getInitialProps(ctx)
return { ...initialProps }
}
render() {
return (
<Html>
<Head>
<link rel="dns-prefetch" href="//www.google.co.jp" />
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
}
export default SampleDocument
_document.js(tsx)では、<Html>, <Head />, <Main />, <NextScript /> がページが適切にレンダリングするために必要となります。このHeadタグの中に<title> など、全ページ共通の設定を行います。
また注意点としては以下のことがあります。
- **SSR(**サーバサイドレンダリング)のみの実行なので、クライアントサイドの処理を書くべきではありません。← 間違いやすいので注意してください!
-
<Main />内に入る外部のReactコンポーネントはブラウザによって初期化されないため、ここでアプリケーションのロジックや、styled-jsxのようなCSSを設定してはいけません。全てのページのコンポーネントに共通させたい場合は代わりにAppコンポーネントを使ってください(_app.js(tsx)に定義) -
DocumentのgetInitialPropsは、クライアントサイドの遷移中には呼び出されず、ページが静的に最適化されている場合にも呼び出されません
次に、_app.js(tsx)の説明をしていきます。
_app.js(tsx)
Next.jsではAppコンポーネントを使用して全てのページを初期化するようになっています。 そのため、このコンポーネントを継承したクラスがあるファイル、_app.js(tsx) を作成することでデフォルトのAppコンポーネントを上書きできます。
つまり、 全ページで必要な処理をここに書くことができます。他にもAppコンポーネントでは以下のようなことができます
- ページ間の共通レイアウトを持たせることができる
- 共通のstateを持つことができる
- グローバルなCSS(全ページ共通の)を定義できる
-
componentDidCatchを利用したカスタムエラー処理 - 各Routeコンポーネントをラップするもの
- ReduxのProvider設定をする
import * as React from "react";
import { Provider } from "react-redux";
function MyApp({ Component, pageProps }) {
return (
<Provider store={store}>
<Layout>
<Component {...pageProps} />
<style jsx global>
{`
#container {
min-width: 800px;
}
`}
</style>
)}
</Layout>
</Provider>
)
}
export default MyApp
また、_document.js(tsx) と異なり、AppはPageコンポーネントと同じ動きをするので、_app.js(tsx)はSSRされ、ライフサイクル周りのイベントはクライアントサイドでも実行することができます。
まとめ
Next.jsではDocument, Appコンポーネントを用いることでページ間の共通処理や共通レイアウトを定義することができます!
_document.js(tsx)にはDocumentコンポーネントを継承したクラスを実装し、共通レイアウトを定義し、_app.js(tsx)ではAppコンポーネントを継承したクラスを定義し、全ページで共通の処理などを書きましょう!
上手く使い分けて、快適なNextライフを送ってください!👨💻
こちらにも記事が載っています: https://tyotto-good.com/blog/next-document-app