スタートアップと協業してサービス開発を推進する中で、Google Analytics(以下GA)を利用してユーザー動向を解析するニーズがありました。ここではその際に必要とした実装に関して記載します。

GAをアプリケーションに導入するには アプリの開発が得意な開発チーム  サービス運用に長けているスタートアップ企業のプロダクトオーナー(以下PO) の知識を集約できていませんでした。
特徴としては次のような状況でした。

  • 開発チームはGAを利用したアプリの開発、運用の経験が無い
  • POはGAを利用していくつかサービスを立ち上げた経験があり、GAに関する知識はある
  • POは採用した技術(SPAがなにか)は分かっているが、詳細は理解していない
    そのため、それまで利用してきたGoogleTagManager(以下GTM)で解析できると思っている

POの経験を元にした実装

アプリケーションを開発し始めたタイミングでPOから「このスクリプトタグを設定してください」と依頼を受けGTMの設定を行いました。 アプリケーションを起動するとGAに情報が送信されていることをPOに確認してもらい、「サービスを利用しているユーザーの動きを解析できる」という要望は実装したと認識していました。
このときは1画面しかないためページの遷移で情報が集まるかまでは検証できていませんでしたが いままでのPOの経験もあり、開発チームともに実現できていると思っていました。

PoC直前に運用も含めた検証を始めたところアプリの初期表示の解析結果しか出なかったため、POが設定を間違えていないか、初期に依頼した設定が入っているかということを開発チームに調査依頼がありました。 初期の依頼を受けたとおりに設定していましたがそもそもSPAでGTMが使えないのではないかと思い調査しました。

SPA(React)に合わせた実装

react google analytics」というキーワードでインターネットを検索して原因と実装方法はすぐにわかりました。

Qiitaに投稿されていた参考記事のように history#listen にイベントハンドラを登録してページ遷移によるユーザーの動きを解析できるようになりました。下記に実装イメージを記載します。

import { createBrowserHistory } from "history";
import ReactGA from 'react-ga';

class App extends React.Component {

  history = createBrowserHistory();

  async componentDidMount() {

    ReactGA.initialize("UA-XXXXXXXX-X");

    this.history.listen(({ pathname }) => {
      ReactGA.set({ page: pathname });
      ReactGA.pageview(pathname);
    });

    const { pathname } = this.history.location;
    ReactGA.set({ page: pathname });
    ReactGA.pageview(pathname);    
  }

}

実装自体はすぐに終わりましたがPOから一部の機能で必要な情報がとれないという相談がありました。 情報がとれない該当のページは商品がカテゴリ毎の一覧になっており、タブで左右に切り替えられる機能のあるページでした。

ページ遷移が発生しない画面のサポート

商品はカテゴリに分かれており、1つのカテゴリに商品を一覧で出すため Ant Design MobileのTabsを利用していました。Tabsの機能でページの遷移ではなくタブを切り替えて操作するためページ遷移によるユーザーの動きの解析では、評価したい情報が取得できませんでした。

評価したい情報は商品を見ている時間ではなくどのカテゴリがよく参照されているかであり、その結果からよく参照されているカテゴリの商品の登録を増やしたいという狙いがありました。

参考にした実装方法ではページの遷移をトリガーにしていたため、タブの切り替えでも情報を送信するように実装して評価したい情報を取得できるようになりました。

ここまで実装したところでPOからOKをもらい「サービスを利用しているユーザーの動きを解析できる」という要望を満たすことができました。

実際の実装イメージを抜粋して下記に記載します。

import React from "react";
import { Router } from "react-router";
import { Route, Redirect } from "react-router-dom";
import { createBrowserHistory } from "history";
import ReactGA from 'react-ga';
import ItemListPage from "./components/pages/ItemListPage";

class App extends React.Component {
  history = createBrowserHistory();

  // 通知用の関数
  analytics(pathname) {
    if (pathname !== "/items") {
      ReactGA.set({ page: pathname });
      ReactGA.pageview(pathname);
    }
  }

  async componentDidMount() {

    ReactGA.initialize("UA-XXXXXXXX-X");

    // ページ遷移のイベントハンドラ。
    this.history.listen(({ pathname }) => {
      this.analytics(pathname);
    });

    // 初期表示の通知
    const { pathname } = this.history.location;
    this.analytics(pathname);

    return (
      <Router history={this.history}>
      <Route exact path="/" render={ () => (  <Redirect to="/items" />) }/>
      <Route exact path="/items" component={ItemListPage} />
      </Router>
    );
  }

}
import React from "react";
import { Tabs } from "antd-mobile";
import { Sticky, StickyContainer } from "react-sticky";
import ReactGA from 'react-ga';


/**
 * カテゴリ毎に表示を行うページ。
 */
export default class ItemListPage extends React.Component {
  analytics(location, tab) {
    const pathname = `${location.pathname}#${tab.title}`
    ReactGA.set({ page: pathname });
    ReactGA.pageview(pathname);
  }

  render() {
    return (
      <StickyContainer>
        <Tabs tabs={items.tabs} initialPage={items.tab} page={items.tab}   
          renderTabBar={props => (
            <Sticky>
              {({ style }) => (
                <div style={{ ...style, zIndex: 1 }}>
                  <Tabs.DefaultTabBar {...props} page={3} />
                </div>
              )}
            </Sticky>
          )}
          onChange={(tab, index) => {
            setTab(index); // tabの切り替え
            this.analytics(history.location, tab); // 遷移先の情報の記録
          }}>
        </Tabs>
      </StickyContainer>
    );
  }
}

おわりに

これまで企業内の基幹システムのアプリケーション開発を多く担当していた私にとって、この案件は私にとって初めてのサービス開発案件でした。 一般ユーザーを対象にPoCでビジネスを評価するという経験も初めてのことでした。
そのこともあり、当初「ユーザーの動きを記録してサービスの評価をする」という要望を意識していませんでした。 ユーザーが利用する機能の開発やサービスのUXに注力することも重要ですが、ユーザーの動きを評価する方法は優先度が低くなってしまいました。

今回の経験から、ビジネス上必要な機能を実装するだけでなく、「サービス(ビジネス)そのものの評価方法を実装する」という必要性を学びました。
実際に評価できそうかどうかも含めて検証するためにも、開発をスタートするときに「これから作るサービスをプロダクトオーナーがどう評価するのか」について、開発者チームとして関心を持つようになりました。


本コンテンツはクリエイティブコモンズ(Creative Commons) 4.0 の「表示—継承」に準拠しています。