おはこんハロチャオ~
ということで最近Next.js13でポケモン関連のwebアプリを作ったのですが、
Next.js13のApp Directryを触れるのが初めてだったので苦戦。。。
特にAnalyticsは避けて通れないのにもかかわらず日本語の情報が不足している感じがしたので、解決方法をお伝えできればと思います
ちなみに作ったのは、ポケモンのタイプ相性を詳細に知れるサービスです
バトル向けに使いやすい機能を追加していくつもりなので、よかったら見ていってください
前提
Google Analyticsを導入した回数もそんなに多くないので、前と同じように調べながら進めていました。
とりあえず、このようなサイトを使ってあーこんなのあったなで進めていきました
一応、これはClient Componentを使うべきだと思ったので、layout.tsx
から切り離して作ったりしました
周辺はこんな感じになっています
import GoogleAnalytics from "../components/GoogleAnalytics";
const Head = () => {
return (
<>
// title, metaなど省略
<GoogleAnalytics />
</>
);
};
export default Head;
export const GA_MEASUREMENT_ID = process.env.NEXT_PUBLIC_GA_ID || "";
export const existsGaId = GA_MEASUREMENT_ID !== "";
export const pageview = (path: string) => {
window.gtag("config", GA_MEASUREMENT_ID, {
page_path: path,
});
};
GA_IDについては.env.local
に入れておきます
NEXT_PUBLIC_
を忘れずに
NEXT_PUBLIC_GA_ID=********
gtagについては型がないのでインストールします
yarn add -D @types/gtag.js
/// <reference types="gtag.js" />
declare module 'gtag.js';
実際にGAのコードを呼び出したりする部分はclient componentとして切り分けましたが、そこで問題が発生しました
起きた問題:router.eventsできないんだけど
問題が起きたのはここです
"use client";
import { useRouter } from "next/router";
import Script from "next/script";
import { useEffect } from "react";
import { existsGaId, GA_MEASUREMENT_ID, pageview } from "../lib/gtag";
const GoogleAnalytics = () => {
const router = useRouter()
useEffect(() => {
if (!existsGaId) return
const handleRouteChange = (path) => pageview(path)
router.events.on('routeChangeComplete', handleRouteChange)
return () => {
router.events.off('routeChangeComplete', handleRouteChange)
}
}, [router.events])
return (
<>
<Script
strategy="lazyOnload"
src={`https://www.googletagmanager.com/gtag/js?id=${GA_MEASUREMENT_ID}`}
/>
<Script id="gtag-init" strategy="afterInteractive">
{`
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', '${GA_MEASUREMENT_ID}', {
page_path: window.location.pathname,
});
`}
</Script>
</>
);
};
export default GoogleAnalytics;
ここのrouter.events
でエディタから「そんなのないよ」って言われちゃいました
どうやらNext.js 13から router.eventsがサポートされていないよう
解決法
同じケースないかなーって探しているとGoogle Analyticsではありませんがこんなのを見つけました
うーん、どうやらnext/navigation
に移行するらしい?
でも情報が少ない
と思ったら、参考にしたブログを作っている方がZennでいろいろ発信していました
灯台下暗しって感じですね、、、
こちらのdiscussionによると、どうやらこれからはこんな感じで置き換えてとのこと
'use client'
import {usePathname, useSearchParams} from 'next/navigation'
function useNavigationEvent() {
const pathname = usePathname()
const searchParams = useSearchParams()
useEffect(() => {
const url = pathname + searchParams.toString()
sendSomewhere(url)
}, [pathname, searchParams])
}
完成型
ということでそれに合わせて変更を入れて完成です
"use client";
import { usePathname, useSearchParams } from "next/navigation";
import Script from "next/script";
import { useEffect } from "react";
import { existsGaId, GA_MEASUREMENT_ID, pageview } from "../lib/gtag";
const GoogleAnalytics = () => {
const pathname = usePathname();
const searchParams = useSearchParams();
useEffect(() => {
if (!existsGaId) {
return
}
const url = pathname + searchParams.toString()
pageview(url)
}, [pathname, searchParams])
return (
<>
<Script
strategy="lazyOnload"
src={`https://www.googletagmanager.com/gtag/js?id=${GA_MEASUREMENT_ID}`}
/>
<Script id="gtag-init" strategy="afterInteractive">
{`
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', '${GA_MEASUREMENT_ID}', {
page_path: window.location.pathname,
});
`}
</Script>
</>
);
};
export default GoogleAnalytics;
参考になるとうれしいです
作ったサービスもよかったら見ていってください