Next.jsPagesRouterでGoogleTagManagerをheadタグに挿入する
Next.jsのPagesRouterを採用している案件で、 <head>
タグにGoogleタグマネージャーを挿入する依頼があり、少々手こずったのでメモ。
まず、全てのページの <head>
に含めたかったので _document.tsx
に以下のように記載してみる。
// _document.tsx
import { Html, Head, Main, NextScript } from 'next/document'
export default function Document() {
return (
<Html lang="ja">
<Head>
<GoogleTagManager />
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
// GoogleTagManager.tsx
import { Script } from 'next/script'
export const GoogleTagManager = () => (
<Script
// ...省略
/>
)
しかしこれでは head
に表示されなかった。(ブラウザレンダリング後のDOMとHTMLレスポンスどちらも)
なので、以下のように Script
を直接 _document.tsx
に記載してみる。
export default function Document() {
return (
<Html lang="ja">
<Head>
<Script
// ...省略
/>
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
するとブラウザレンダリング後のDOMの head
タグにGTMが表示された。
(ただ、HTMLレスポンスには含まれていないのでクライアント側で生成されたっぽい)
公式ドキュメントを見てみる👀
どうやら strategy
プロパティを使用すると Script
の実行タイミングを操作できるみたい🧐
beforeInteractive
: サーバー側で初期 HTML に挿入されるafterInteractive
: クライアント側でハイドレーション発生後に挿入されるlazyOnload
: クライアント側で全てのリソースを取得した後に挿入される
他にも worker
や onLoad
…などあるがタイミングを操作できるのは👆の3つっぽい。
なので、👆の中の beforeInteractive
を使用したらサーバー側で head
に挿入してくれる。
// _document.tsx
import { Html, Head, Main, NextScript } from 'next/document'
export default function Document() {
return (
<Html lang="ja">
<Head>
<Script
strategy={beforeInteractive} 👈ここに記述
// ...省略
/>
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
これで初期 HTMLの head
にも含まれていてブラウザのDOMにも表示されたので一件落着🙌
最近はNext.jsのAppRouterを使うことが多いので本件はだいぶ手こずった💦
だいぶAppRouter色に染まってしまっている。。。