Next.jsでは、HeadにScriptタグは使えません!
最初に結論
Next.jsには、Head
タグ内にScript
タグが入った場合はScript
タグを無視するという仕様があります
No Script Tags In Head Component
v11からの仕様のようでした
https://nextjs.org/docs/basic-features/script > Version History
v11.0.0
next/script
introduced.
どうしたらいい?
Head
タグの外に、Script
タグを書きましょう
※ Head
タグに含めなければ、自動で<body>
に入ります
import Head from 'next/head'
import Script from 'next/script'
export default function App({ Component, pageProps }: AppProps) {
return (
<>
<Script src="..." />
<Component {...pageProps} />
</>
)
}
経緯
そもそもは、next.jsのチュートリアルで作ったアプリに、GTM (Google Tag Manager) を設置しようと思ったことがきっかけです
最初の実装
最初はReact
/GTM
のワードで調べて、「Reactでも、普通のアプリと同じように<head>
内に置けばいい」とわかり、下記のように書きました
- GTMタグを component として作成して
// components/gtm.tsx
import Script from "next/script";
export const GoogleTagManager: React.FC<{
googleTagManagerId: string;
}> = ({ googleTagManagerId }) => (
<Script
id="gtm"
strategy="afterInteractive"
dangerouslySetInnerHTML={{
__html: `
function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','${googleTagManagerId}');
`,
}}
/>
);
- (全ページ共通の
Layout
コンポーネントがあるので、)Head
内で読み込み
// components/layout.tsx
import { GoogleTagManager } from "./gtm";
...
<Head>
<GoogleTagManager googleTagManagerId={/*GTM_TAG*/} />
...
</Head>
が、どんなにローカルを更新しても、GTM用の<script>
タグが出てこない…🤔
警告も出てなさそうだしなんで??と悲しみつつ、
React
/Next
/head
/script
のワードで調べ直したところ、
最初に紹介した、公式ドキュメントにたどり着き、仕様だということがわかりました!
No Script Tags In Head Component
最終的な実装
最初に紹介したコードとほぼ同じですが、下記のようになりました<script>
タグが読み込まれているのも確認できました😆
残念ながら<body>
の下の方に表示になってしまって、 GTMの推奨位置(<head>
の一番上)とは違う位置になってしまったのですが、表示されないよりいいでしょう😆
実はESLintにはちゃんとエラーがあった
今回、最初からGTM専用のコンポーネントを作ってしまったことも、私がしばらくエラーに気づけなかった原因の一つでした
Head
の中にScript
タグそのものがある場合は、きちんとESLintのエラーが表示されました
公式の実装例
Next.jsはチュートリアルはもちろん、実装例も豊富です
GTM設置用の実装例もありました
ここでは当然、Head
の外にScript
タグが書かれています
が、散々Head
を追っていた自分の目には、Component
タグが全然入ってこず…😱
「なんで同じようなScript
タグ置いてるのにダメなんだろう…」と思って、気づくまでに時間がかかりました😭
これから、Next.js始めよう! & GAやGTMを設置しよう!と思っている方は、ぜひ最初にexamples
フォルダを見てみてください!😉
Discussion