_app.tsxとは
/page/_app.tsx
を作成することでAppコンポーネントをカスタマイズができる。
すべてのページコンポーネントの初期化に使われるコンポーネント。
すべてのページで共通な処理などを書くことができる。
_documment.tsxとは
/page/_documment.tsx
を作成することでDocumentコンポーネントをカスタマイズができる。
htmlタグやbodyタグの定義を行うコンポーネント
ページ共通のheadタグなどを定義する
_app.tsxの例
import { AppProps } from 'next/app'
import Head from 'next/head'
const App = ({ Component, pageProps }: AppProps) => (
<>
<Head>
<title />
<meta name='viewport' content='width=device-width, initial-scale=1' />
</Head>
<Component {...pageProps} />
</>
)
export default App
_documents.tsxの例
import NextDocument, { Html, Head, Main, NextScript } from 'next/document'
type Props = {}
class Document extends NextDocument<Props> {
render() {
return (
<Html lang="ja-JP">
<Head>
<meta charSet="utf-8" />
<meta name="format-detection" content="telephone=no" />
<link rel="shortcut icon" href={'/favicon.ico'} />
<link rel="apple-touch-icon" href={'/logo.png'} />
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
}
export default Document
※NextDocumentクラスの継承が必要
_app.tsxと_documents.tsxは全ページ共通に設置しておきたい処理を記述できます。
アナリティクスタグなんかも設置していいと思います。
注意点として_documents.tsxには
<title />
タイトルタグや
<meta name='viewport' content='width=device-width, initial-scale=1' />
metaのviewportは設置すると怒られるみたいなので、
_app.tsxに記述しましょう。
Contextで共通なグローバルな値を管理する
_app.tsxは全ページ共通になるので、グローバルな値を管理するのにも使えます。
カスタムhookにAppContextがあるていです。
import { AppProps } from 'next/app'
import Head from 'next/head'
import { AppContext } from '@hooks/useApp'
const App = ({ Component, pageProps }: AppProps) => (
const value = '値'
<>
<Head>
<title />
<meta name='viewport' content='width=device-width, initial-scale=1' />
</Head>
<AppContext.Provider value={value}>
<Component {...pageProps} />
</AppContext.Provider>
</>
)
export default App
こんな感じで_app.tsxにContextを設置しておけばグローバルな値として、
全てのページで共通の値を使えます。
ページごとにmetaなどを変えたい場合
ページによってタイトルやmeta情報を変更したい場合があると思います。
まずはheadタグまとめたコンポーネントを作ってあげます。
import * as React from 'react';
import Head from 'next/head';
export default ({ title, description, keyword, image, url }: Props) => {
return (
<Head>
<title>{title}</title>
<meta property="og:title" content={title} />
<meta property="og:description" content={description} />
<meta name="keywords" content={keyword} />
<meta property="og:type" content="blog" />
<meta property="og:url" content={url} />
<meta property="og:image" content={image} />
<meta property="og:site_name" content={title} />
<meta name="twitter:card" content="summary" />
<meta name="twitter:site" content="text.jp" />
<meta name="twitter:url" content={image} />
<meta name="twitter:title" content={title} />
<meta name="twitter:description" content={description} />
<meta name="twitter:image" content={image} />
</Head>
);
};
import Head from 'next/head';
function testPage() {
return (
<>
<Head
title={'タイトル'}
description={'ディスクリプション'}
keyword={'キーワード'}
image={'/img.jpg'}
url={'https://test.jp'}
/>
</>
);
}
export default testPage;
こうしてあげると各ページごとにタイトルやmetaを設定することができます。
_documment..tsxと_app.tsxについてと
ちょっとした派生的な実装をご紹介いたしました。
(実際に動かしたわけではないので、なにかあればご指摘いただけますと幸いです。。)