トラッキングコードを挿入するコードについて調べてみた

Google Tag Managerなどでよくあるこいつ、いい加減ちゃんと何してるか知ろうと思って調べてみました。 基本構造 やっていることはscriptタグをDOMに追加しているだけです。ロードされたときに1度実行され […]

広告ここから
広告ここまで

目次

    Google Tag Managerなどでよくあるこいつ、いい加減ちゃんと何してるか知ろうと思って調べてみました。

        <script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
        new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
        j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
        'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
        })(window,document,'script','dataLayer','GTM-XXXXXX');</script>

    基本構造

    やっていることはscriptタグをDOMに追加しているだけです。ロードされたときに1度実行されればよいので、即時関数(IIFE: Immediately Invokable Function Expression)かつminifyされているために慣れないと??となるコードになっています。

    見慣れた書き方にするとこうなります。

    function addGtagScript(window, document, tagName, layer, id) {
      window[layer] = window[layer] || [];
      window[layer].push({
        'gtm.start': new Date().getTime(),
        event: 'gtm.js'
      });
      var func = document.getElementsByTagName(tagName)[0],
          script = document.createElement(tagName),
          dataLayer = layer != 'dataLayer' ? '&layer=' + layer : '';
      script.async = true;
      script.src =
          'https://www.googletagmanager.com/gtm.js?id=' + id + dataLayer;
      func.parentNode.insertBefore(script, func);
    }
    addGtagScript(window, document, 'script', 'dataLayer', 'GTM-XXXXXX');

    オレオレトラッキングコードを作る

    ということがわかれば、自前のトラッキングコードを作ることも可能ですね。

    function myTrackingCode(window, document, tagName, src, funcName) {
      const func = document.getElementsByTagName(tagName)[0]
      const script = document.createElement(tagName)
      script.async = true
      script.src = src
      func.parentNode.insertBefore(script, func)
    }
    myTrackingCode(window, document, 'script', 'https://example.com', 'myTracking')

    例えば上記のスクリプトを埋め込むと、HTMLに以下のようなコードが挿入されます。

    <script async src="https://example.com"></script>

    minifyと即時関数化を施すとこうなります。

    <script>
    !function(e,t,n,a,c){var r=t.getElementsByTagName(n)[0],m=t.createElement(n);m.async=!0,m.src="https://example.com",r.parentNode.insertBefore(m,r)}(window,document,"script");
    </script>

    それっぽくなりましたね。

    イベントトラッキングにも対応する

    即時関数内でwindowに関数を足してやればOKです。

    (function (window, document, tagName, src, funcName) {
      window[funcName] = window[funcName] || function(name) {
        console.log(`hello: ${name}`)
      }
      const func = document.getElementsByTagName(tagName)[0]
      const script = document.createElement(tagName)
      script.async = true
      script.src = src
      func.parentNode.insertBefore(script, func)
    })(window, document, 'script', 'https://example.com', 'myTracking')
    
    myTracking('john')

    2 ~ 4行目でwindowオブジェクトにトラッキング用の関数を追加しています。

    そのほか

    SaaS側はだいたい「index.htmlにこれ貼ってね。ユーザー名は動的に変更よろしく!」のように案内されます。

    ただReact / AngularなどでSPA(SSRなし)を作っていると、「いや、ユーザー名すぐ取れないんだけど・・・」となることもあります。大手系はトラッキング用のライブラリがnpmにあることが多いですが、公式でないケースや誰も作ってないことも少なくない状態。

    そういう時に挿入するトラッキングコードがどういう動きしてるかを知っていると、「あ、じゃあここだけ別の場所に書けばいいか」と判断できたりして便利です。

    広告ここから
    広告ここまで
    Home
    Search
    Bookmark