Tabelog Tech Blog

食べログの開発者による技術ブログです

Next.jsへAdobe Analyticsを導入した話

はじめに

この記事は 食べログアドベントカレンダー 2022 の 5 日目の記事です 🎅🎄

こんにちは、フロントエンドチームの荒川です。 本日は食べログノートという新サービスを立ち上げるにあたり、Adobe Analytics を Next.js に導入したことについてご紹介します。

導入にあたって他の事例を調べてみたところ、日本語の参考になる文献あまり無かったため、今後導入する皆さんの参考になれば幸いです。

食べログノートのご紹介

食べログノートは、食べログネット予約をご利用している店鋪さま向けの予約管理台帳です。 食べログネット予約で受け付けた内容を、タイムライン上で確認・管理したり、 電話予約などで受け付けた内容をシステムへ登録することができます。

タイムスケジュールなど主要な画面のフロントエンドをほぼ Next.js & TypeScript で実装しており、 バックエンドの Ruby on Rails と GraphQL を介してデータをやりとりする構成になっています。

Adobe Analytics とは

今回登場する Adobe Analytics は Web サイトに JavaScript を埋め込むことで、ユーザーの行動をトラッキングするビーコン型と呼ばれるアクセス解析ツールです。 類似のツールとして最大のシェアがある Google Analytics と比較すると、取得するデータの自由度が高く、データの活用方法も多岐にわたりますが、その分導入や設定が複雑で、データ量に基づいた課金が必要になっています。

食べログノートでは、PV(ページビュー)数を画面の表示ごとに計測するため、Adobe Analytics を利用します。

next/router のイベント

公式の example を確認すると、google-analytics のケースがあったので、こちらを参考に実装を進めることにしました。

こちらのコードを確認すると、Google Analytics で PV を送信する処理が実装されていました。

  useEffect(() => {
    const handleRouteChange = (url) => {
      gtag.pageview(url)
    }
    router.events.on('routeChangeComplete', handleRouteChange)
    router.events.on('hashChangeComplete', handleRouteChange)
    return () => {
      router.events.off('routeChangeComplete', handleRouteChange)
      router.events.off('hashChangeComplete', handleRouteChange)
    }
  }, [router.events])

router に対して Event Listener が貼られていますね。 routeChangeComplete, hashChangeComplete はどのようなタイミングで発生するか、 Next.js の API Reference を確認すると

  • Next.js - router.events
    • routeChangeComplete(url, { shallow }) - ルーティングの完了時に発火する
    • hashChangeComplete(url, { shallow }) - ページではなくハッシュの変更時に発火する

となっていました。 このように、next/router の上記の Event に hook すれば期待通りにページが遷移した時に PV を送信できそうです。

実装の例

Adobe Analytics ではビーコン発信用の script を読み込み、その script 中の関数を PV 計測したいタイミングで呼び出します。 ビーコン発信用の script は Adobe から配布されていて、global 変数として扱うことになるので、TypeScript 用の型定義を別途作成しました。

実際に作成した型定義は以下の通りです。

interface Window {
  s_account: string;
  s_gi: (namespace: string) => Record<string, unknown> & {
    tl: (window: Window, type: string, value: string) => void;
    t: () => void;
  };
}

declare let s_account: Window["s_account"];
declare let s_gi: Window["s_gi"];
  • functions - s_gi データ送信用の Object を作成します。
  • functions - t PV を計測するトラッキングデータを送信します。
  • functions - tl トラッキングデータを送信します。tとは異なり、こちらの送信で PV のカウントは行われません。

今回のサービスでは hash の変更を PV として扱わないので、ルーティングの完了時のみ PV 計測のデータを送信することとしました。 hooks に router の EventListener を作成し、こちらをページ初期化用コンポーネントである pages/_app.jsで読み込んでいます。

実際のコードはもう少し複雑ですが、以下のような実装になりました。

export const usePageView = (): void => {
  const router = useRouter();
  const onPageView = useCallback(() => {
    const s = s_gi(s_account);
    s.t();
  }, []);

  useEffect(() => {
    router.events.on("routeChangeComplete", onPageView);

    return () => {
      router.events.off("routeChangeComplete", onPageView);
    };
  }, [onPageView, router.events]);
};

動作確認

Adobe Analytics には GoogleChrome のプラグインとして、Adobe Experience Platform Debugger というデバッグツールが提供されています。 こちらを利用して、実際に画面を表示した時の状態を確認してみます。

インストール後、Chrome の拡張機能から選択すると、デバッガーのウィンドウが表示されます。 この状態で実装後のページを表示すると、デバッガーが以下の表示になりました。

URL やページタイトル、アクセス時刻などが送信されているのが確認できますね!

まとめ

今回は Adobe Analytics を Next.js に導入する方法についてご紹介しました。 データ送信のタイミングは他のビーコン型のアクセス解析ツールでも応用できそうですね。

食べログのフロントエンドチームでは、React, Next.js, GraphQL などを利用してモダンフロントエンド開発を行っているので、 今後も開発にまつわる Tips などをご紹介していきたいと思います。

明日は @saten_qiita の「気持ち良くより良い仕事をするために雑談をしよう」です。お楽しみに!

最後に

現在、食べログではフロントエンドに関わるポジションとして以下の2つを募集しています。 気になったかたは是非チェックしてみてください!

  • 難しい課題にチーム一丸となって取り組みたい
  • React/TypeScript でバリバリ開発したい
  • レガシーなシステムのリファクタリングがしたい
  • アーキテクチャについて探求したい
  • 食べログというプロダクトに貢献したい
  • 大規模なシステムの開発に携わりたい
  • 柔軟に働ける環境で自分のスキルを活かしたい

どれかに当てはまった方は以下のリンクも是非御覧ください!