
Next.js App Router に GTM と GA4 を導入する方法
このブログに Google Tag Manager(GTM)経由で Google Analytics 4(GA4)を導入しました。 Next.js の公式パッケージを使えば、驚くほど簡単に実装できたので、その方法を共有します。
なぜ GTM 経由なのか
GA4 を直接埋め込む方法もありますが、GTM 経由にするメリットがあります:
- タグの一元管理: GTM 上で様々なタグ(GA4、広告、ヒートマップなど)を管理できる
- コード変更不要: 新しいタグの追加や設定変更が GTM の管理画面だけで完結
- 柔軟なトリガー設定: 特定のイベントやページビューに対して細かい制御が可能
- バージョン管理: 変更履歴が残り、問題があればロールバックできる
将来的に他のツールを導入する可能性を考えると、最初から GTM で管理しておくのがおすすめです。
使用するパッケージ
Next.js 公式が提供している @next/third-parties パッケージを使います。
このパッケージは、Google Tag Manager、Google Analytics、YouTube 埋め込みなど、サードパーティサービスの統合を最適化してくれます。
主なメリット:
- パフォーマンスを考慮した遅延読み込み
- Server Components との互換性
- 公式サポートによる安心感
導入手順
1. パッケージのインストール
npm install @next/third-parties
2. GTM コンテナの作成
まだ GTM コンテナがない場合は、Google Tag Manager で新規作成します。
- GTM にログイン
- 「アカウントを作成」をクリック
- アカウント名とコンテナ名を入力
- ターゲットプラットフォームで「ウェブ」を選択
- 作成後、
GTM-XXXXXXX形式のコンテナ ID を控えておく
3. layout.tsx に GTM を追加
App Router の場合、app/layout.tsx に追加します:
import { GoogleTagManager } from "@next/third-parties/google";
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="ja">
<GoogleTagManager gtmId="GTM-XXXXXXX" />
<body>
{children}
</body>
</html>
);
}
これだけです。
<html> タグの直下、<body> の前に <GoogleTagManager /> コンポーネントを配置するだけで、GTM の導入が完了します。
4. GTM で GA4 タグを設定
次に、GTM の管理画面で GA4 タグを設定します。
タグの作成
- GTM 管理画面で「タグ」→「新規」をクリック
- タグの種類で「Google アナリティクス: GA4 設定」を選択
- 測定 ID(
G-XXXXXXX形式)を入力
トリガーの設定
- トリガーで「All Pages」を選択(全ページでタグを発火)
- タグを保存
公開
- 右上の「送信」ボタンをクリック
- バージョン名を入力して「公開」
これで GA4 がサイト全体で有効になります。
実際のコード
このブログの app/layout.tsx は以下のようになっています:
import type { Metadata } from "next";
import { Geist, Geist_Mono } from "next/font/google";
import { GoogleTagManager } from "@next/third-parties/google";
import "./globals.css";
import { Header } from "@/components/Header";
import { Footer } from "@/components/Footer";
const geistSans = Geist({
variable: "--font-geist-sans",
subsets: ["latin"],
});
const geistMono = Geist_Mono({
variable: "--font-geist-mono",
subsets: ["latin"],
});
export const metadata: Metadata = {
title: "printemps tokyo blog",
description: "printemps tokyo の技術ブログ",
};
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="ja" suppressHydrationWarning>
<GoogleTagManager gtmId="GTM-MXHXGBCD" />
<body
className={`${geistSans.variable} ${geistMono.variable} antialiased flex min-h-screen flex-col bg-[#002b36]`}
>
<Header />
<main className="flex-1 bg-[#002b36]">
{children}
</main>
<Footer />
</body>
</html>
);
}
ポイントは <GoogleTagManager gtmId="GTM-MXHXGBCD" /> の1行だけ。
非常にシンプルです。
環境変数で GTM ID を管理する
本番環境と開発環境で GTM コンテナを分けたい場合は、環境変数を使うことをおすすめします:
// app/layout.tsx
<GoogleTagManager gtmId={process.env.NEXT_PUBLIC_GTM_ID || ""} />
# .env.local(開発環境)
NEXT_PUBLIC_GTM_ID=GTM-XXXXXXX
# .env.production(本番環境)
NEXT_PUBLIC_GTM_ID=GTM-YYYYYYY
これにより、開発環境でのテスト用コンテナと本番用コンテナを分離できます。
データレイヤーへのイベント送信
カスタムイベントを GTM に送信したい場合は、sendGTMEvent 関数を使います:
"use client";
import { sendGTMEvent } from "@next/third-parties/google";
export function DownloadButton() {
return (
<button
onClick={() =>
sendGTMEvent({
event: "download_click",
category: "engagement",
label: "pdf_download",
})
}
>
ダウンロード
</button>
);
}
GTM 側でこのイベントをトリガーとして設定すれば、GA4 にカスタムイベントとして記録されます。
動作確認
導入後は、以下の方法で動作を確認できます:
1. GTM プレビューモード
GTM 管理画面の「プレビュー」ボタンをクリックすると、タグの発火状況をリアルタイムで確認できます。
2. GA4 リアルタイムレポート
GA4 の「レポート」→「リアルタイム」で、実際にデータが計測されているか確認できます。
3. ブラウザの開発者ツール
「Network」タブで gtm.js や analytics へのリクエストが発生しているか確認できます。
注意点
Cookie 同意について
GDPR や日本の個人情報保護法への対応として、Cookie 同意バナーの実装を検討してください。 GTM には「同意モード」という機能があり、ユーザーの同意状況に応じてタグの動作を制御できます。
開発環境での計測除外
開発中のアクセスが GA4 に記録されてしまう場合は:
- GTM のプレビューモードを使う(計測されない)
- 開発環境用の別コンテナを使う
- IP アドレスでフィルタリングする
まとめ
Next.js App Router に GTM と GA4 を導入する手順:
@next/third-partiesパッケージをインストールlayout.tsxに<GoogleTagManager gtmId="..." />を追加- GTM 管理画面で GA4 タグを設定
- 公開して完了
公式パッケージを使うことで、パフォーマンスを損なうことなく、たった数行のコードで導入できます。
以前は <Script> タグを使って手動で GTM スニペットを埋め込む方法が主流でしたが、@next/third-parties の登場により、よりクリーンな実装が可能になりました。