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.0next/scriptintroduced.
どうしたらいい?
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
最終的な実装
最初に紹介したコードとほぼ同じですが、下記のようになりました
開発者ツールにて、GTM用の<script>タグが読み込まれているのも確認できました😆

残念ながら<body>の下の方に表示になってしまって、 GTMの推奨位置(<head>の一番上)とは違う位置になってしまったのですが、表示されないよりいいでしょう😆
実はESLintにはちゃんとエラーがあった
今回、最初からGTM専用のコンポーネントを作ってしまったことも、私がしばらくエラーに気づけなかった原因の一つでした
Headの中にScriptタグそのものがある場合は、きちんとESLintのエラーが表示されました

公式の実装例
Next.jsはチュートリアルはもちろん、実装例も豊富です
GTM設置用の実装例もありました
ここでは当然、Headの外にScriptタグが書かれています
が、散々Headを追っていた自分の目には、Componentタグが全然入ってこず…😱
「なんで同じようなScriptタグ置いてるのにダメなんだろう…」と思って、気づくまでに時間がかかりました😭
これから、Next.js始めよう! & GAやGTMを設置しよう!と思っている方は、ぜひ最初にexamplesフォルダを見てみてください!😉
Discussion