nuxt.jsでGoogle Analytics 4の設定方法

  • ga
  • google analytics
  • js
  • nuxt

2020/12/14

Nuxt.jsでSSGのサイトを実装した際に、google analyticsを設定するのに手間取ったので共有します。

まず最初にやったこと

next.jsのdocumentに記載されている nuxt/google-analytics を使用してみました。
結論から言うと最近リリースされたgoogle analytics 4に対応しておらず(2020/12現在)、headタグ配下に正しく表示されませんでした。nuxt/google-analyticsの使い方は、こちらを参照してください。

google analyticsで新たにプロパティを作成する際に、ユニバーサル アナリティクス プロパティをOnにして作成すれば、従来と同じトラッキングIDが取得できるので、それを使えばうまく動作するようです。2020年12月現在、nuxt-community関連のissueを漁ってみたが、現在も議論中をしているようです。

できるlibraryもあるように書かれているのですが、まだdocumentが充実しておらずコードを読まないと不明な部分が多いライブラリはできるだけ避けたいので、今回は、自分で実装してみました。

nuxt.config.jsのhead部分に記述してみた

ライブラリが使えないということで、独自実装することにしました。
まずは、安直にnuxt.config.jsのhead部分にgaに出力されるhtmlタグを記述してみました。

export default {
  script: [
    { src: 'https://www.googletagmanager.com/gtag/js?id=G-XXX', async: true },
    { innerHTML: 'window.dataLayer = window.dataLayer || [];function gtag(){dataLayer.push(arguments);}gtag(\'js\', new Date());gtag(\'config\', \'G-XXX\');' }
  ],
  __dangerouslyDisableSanitizers: ['script']
}
これで、うまくはいったもののコード的にイケてない。また、可読性が低いため編集が必要になった際にリファクタしづらい。また、GAのトラッキングIDを直書きする必要があるので、セキュリティ的に微妙。ということで、速攻でボツにしました。

gaタグを作成するplugin を作成

nuxt.jsのdocumentにもカスタマイズする際には、pluginを作成することを薦めていたので、それに則って実装してみました。plugins/配下にga.jsというファイルを作成しました。 
実装したコードは下記のとおりです。

export default ({ app }) => {
  if (process.env.NODE_ENV !== 'production') { return }

  const gaScriptContent = (id) => {
    return (
      `
      window.dataLayer = window.dataLayer || [];
      function gtag(){dataLayer.push(arguments);}
      gtag('js', new Date());
      gtag('config', '${id}');
      `
    )
  }

  ((document) => {
    const srcScriptElement = document.createElement('script')
    srcScriptElement.async = true
    srcScriptElement.src = `https://www.googletagmanager.com/gtag/js?id=${app.context.env.gaTrackingID}`

    const firstLinkElement = document.getElementsByTagName('link')[0]
    firstLinkElement.insertAdjacentElement('beforebegin', srcScriptElement)

    const gaScriptElement = document.createElement('script')
    gaScriptElement.text = gaScriptContent(app.context.env.gaTrackingID)

    firstLinkElement.insertAdjacentElement('beforebegin', gaScriptElement)
  })(document)
}
今回のコードは、基本的にはgoogle analyticsから取得できるタグを参考に実装しています。下図参照。下記ページへの行き方はこちらを参照

GA タグ取得画面
上記を踏まえた上で、念の為に詳しく解説しておきます。

const gaScriptContent = (id) => {
  return (
    `
    window.dataLayer = window.dataLayer || [];
    function gtag(){dataLayer.push(arguments);}
    gtag('js', new Date());
    gtag('config', '${id}');
    `
  )
}
こちらは、google analyticsから取得できるタグのうち、一番最後のscriptタグに記述されているものを使用しています。引数にはトラッキングIDを渡します。

const srcScriptElement = document.createElement('script')
srcScriptElement.async = true
srcScriptElement.src = `https://www.googletagmanager.com/gtag/js?id=${app.context.env.gaTrackingID}`

const firstLinkElement = document.getElementsByTagName('link')[0]
firstLinkElement.insertAdjacentElement('beforebegin', srcScriptElement)
こちらは、google analyticsから取得できるタグのうち一番上のscriptタグを作成しています。上3行でscriptタグの内容を記述しており、最後の2行でdocument内にappendしています。トラッキングIDは引数のappから環境変数を持ってきて取得しています。環境変数の設定方法は後述します。今回は、insertAdjacentElementメソッドを使用していますが、documentと同様insertBeforeでもできます。insertAdjacentElementメソッドの仕様は こちら を参照してください。

const gaScriptElement = document.createElement('script')
gaScriptElement.text = gaScriptContent(app.context.env.gaTrackingID)

firstLinkElement.insertAdjacentElement('beforebegin', gaScriptElement)
ここでは、gaScriptContentを使用して、最後のscriptタグを作成しています。ここでも同様に環境変数からトラッキングIDを取得しています。
最後にこのファイルを nuxt.config.js に読み込めば完了です。

plugins: [
  { src: '~plugins/ga.js', mode: 'client' }
]

所感

まだまだ、リファクタする余地はありますが、意外とうまくいったかなと思っています。documentにあるように汎用的に使えるように実装しても良いと思いますが、今回は静的なページでの使用目的で複雑なことをする予定はなかったのでシンプル実装してみました。
もし、もっとうまい書き方があれば共有いただけると嬉しいです。

余談

環境変数の反映に少しハマったので、自分の備忘録として記述しておきます。今回は、ssgなので next generate するときに環境変数を読み込めるようにしてみました。

NODE_ENV=production GOOGLE_ANALYTICS_ID=GA-XXXX nuxt-ts generate
また、nuxt.config.jsにもenvの設定を追加します。

export default {
  env: {
    gaTrackingID: process.env.GOOGLE_ANALYTICS_ID || 'development'
  }
}
これで、読み込めるようになれると思います。
これももし、もっといい方法があれば共有いただければ嬉しいです。

関連記事