サムネイル

Next.js(App Router)×TypescriptでGoogleアナリティクスを導入する

対象者

  • Next.jsで構築したサイトにGoogleアナリティクスを導入したい方。
  • または、その方法がわからない方。

書かないこと

トラッキングID・gtagの取得の仕方(取得した前提で話を進めます。)

環境

  • next: 14.0.4
  • react: ^18
  • typescript: ^5

導入していく

  • トラッキングID・gtagを環境変数で持っておく
// .env.local
NEXT_PUBLIC_GOOGLE_ANALYTICS_ID="G-****************************"
  • ibs/gtag.tsを作成する
export const GA_TAG_ID = process.env.NEXT_PUBLIC_GOOGLE_ANALYTICS_ID || "";

export const IS_GATAG = GA_TAG_ID !== "";

export const pageview = (path: string) => {
  window.gtag("config", GA_TAG_ID, {
    page_path: path,
  });
};


window.gtag("config", GA_TAG_ID, {
  page_path: path,
});

上記の箇所に目見線が出ていると思うので下記コマンドで型をインストールします。

$ npm i -D @types/gtag.js
  • GoogleAnalyticsコンポーネントの作成
// components/GoogleAnalytics.tsx 
"use client";

import { usePathname, useSearchParams } from "next/navigation";
import Script from "next/script";
import { useEffect } from "react";
import { IS_GATAG, GA_TAG_ID, pageview } from "@/libs/gtag";

const GoogleAnalytics = () => {
  const pathname = usePathname();
  const searchParams = useSearchParams();

  useEffect(() => {
    if (!IS_GATAG) {
      return;
    }
    const url = pathname + searchParams.toString();
    pageview(url);
  }, [pathname, searchParams]);

  return (
    <>
      <Script
        strategy="lazyOnload"
        src={`https://www.googletagmanager.com/gtag/js?id=${GA_TAG_ID}`}
      />
      <Script id="gtag-init" strategy="afterInteractive">
        {`
          window.dataLayer = window.dataLayer || [];
          function gtag(){dataLayer.push(arguments);}
          gtag('js', new Date());
          gtag('config', '${GA_TAG_ID}', {
            page_path: window.location.pathname,
          });
        `}
      </Script>
    </>
  );
};

export default GoogleAnalytics;
  • layout.tsxでGoogleAnalyticsコンポーネントを読み込む
// layout.tsx

import { Inter } from "next/font/google";
import "./globals.css";
import GoogleAnalytics from "@/components/GoogleAnalytics";
import { Suspense } from "react";
export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="ja" className="scroll-smooth">
      <head>
        <Suspense fallback={null}>
          <GoogleAnalytics />
        </Suspense>
      </head>
      <body className={inter.className}>
        {children}
      </body>
    </html>
  );
}

ここで少し注意が必要なんですけど、Next.jsでApp Routerを使用するときにuseSearchParams()を使用すると、Entire page deopted into client-side renderingというエラーが出てしまいます。
https://nextjs.org/docs/messages/deopted-into-client-rendering

その対処方法として、useSearchParams()を使用しているコンポーネント(今回の場合、GoogleAnalytics.tsx)に<Suspence />でラップしてやるとエラーが無くなります。

以上でGoogleアナリティクスを導入できました。