目次

ServiceWorkerの削除と登録解除をGTM(Google Tag Manager)で実装する


GTM (Googleタグマネージャ) を利用して使わなくなったServiceWorkerの削除と登録解除をする。

前回、「旧サイトで利用していたServiceWorkerが原因でCSSが更新されない」として原因がわかったので、解決編。

解決のためにJSファイルをサーバに設置して任意のタイミングで読み込ませることを考えましたが、せっかくなのでGTM (Googleタグマネージャ / Google Tag Manger) を利用することにしました。

GTM (Google Tag Manager) とは。

GTMとは、Googleが提供しているタグマネジメントツールのことです。「タグ」とはWEBサイトに仕込めるHTMLタグのことで、おおよそなんでも設定できます。Googleが提供する機能や、自分で設定した機能を「タグ」として管理して任意のタイミングで発火することが可能です。

今回は、このサイトのすべてのページで、ServiceWorkerを削除するJavaScriptを自動実行することを目指します。

ページが見つかりませんでした

                </div>
            </div>
        </div>
        <div class="embed-footer">
            <a href="https://support.google.com" target="_blank">
                <img src="https://www.google.com/s2/favicons?domain=support.google.com" alt="" title="ページが見つかりませんでした" class="favicon">
                https://support.google.com
            </a>
        </div>
    </div>
</div>

HugoサイトにGTMを設定する

Hugoは、デフォルトでは、Google Analyticsにしか対応していません。そこで、GTMを実行できるようにHugoの拡張を行います。

まず、GTMのプロパティを、config.tomlに追加します。Hugoのデフォルトにはないパラメータのため、Params以下に設定を追加します、

config.toml
1
2
[params]
  googleTagManager = "GTM-******"

上記の設定で'{{ .Site.Params.GoogleTagManager }}'で呼び出せるようになります。

GTM用のパーツを追加用意してbaseof.htmlに追加する。

GTMを追加するためには<head><body>のそれぞれにGTM呼出用のコードを追加します。GTMの管理画面にある「Google タグ マネージャーをインストール」から確認が可能ですが、自分のGTMのIDが埋め込まれている以外は全員共通です。そこで、Hugo用のテンプレートパーツにして、先ほど追加した'{{ .Site.Params.GoogleTagManager }}'を埋め込むようにします。

Hugo用のGTMのheaderパーツ

HugoのテンプレートパーツとするGoogle Tag Mangerのheaderパーツは以下となりました。

gtm-head.html
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
<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', '{{ .Site.Params.GoogleTagManager }}');
</script>

Hugo用のGTMのbodyパーツ

HugoのテンプレートパーツとするGoogle Tag Mangerのbodyパーツは以下となりました。

gtm-body.html
1
2
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id={{ .Site.Params.GoogleTagManager }}"
    height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>

カスタムテンプレートパーツとして、保存する

カスタムテンプレートパーツとして、site/layouts/partials/ 配下にgoogletagmanagerディレクトリを作って格納します。

1
2
3
4
site/layouts/partials/
└── googletagmanager
    ├── gtm-body.html
    └── gtm-head.html

baseof.htmlに追記する

googletagmanager/gtm-head.htmlパーツはheaderの可能な限り最初に読み込ませるように設定します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
--- a/site/layouts/_default/baseof.html
+++ b/site/layouts/_default/baseof.html
@@ -7,6 +7,7 @@
 <!DOCTYPE html>
 <html lang="{{ .Site.LanguageCode }}">
     <head>
+        {{ partial "googletagmanager/gtm-head.html" . }}
         <meta charset="utf-8">
         <meta name="viewport" content="width=device-width, initial-scale=1">
         <meta name="robots" content="noodp" />

bodyパーツも同様になるべくbodyタグ開始直後に設定します。

1
2
3
4
5
6
7
8
9
--- a/site/layouts/_default/baseof.html
+++ b/site/layouts/_default/baseof.html
@@ -27,7 +27,7 @@
     </head>
     {{- if ne $offline true -}}
     <body data-header-desktop="{{ .Site.Params.header.desktopMode }}" data-header-mobile="{{ .Site.Params.header.mobileMode }}">
+        {{ partial "googletagmanager/gtm-body.html" . }}
         {{- /* Check theme isDark before body rendering */ -}}
         {{- $theme := .Site.Params.defaulttheme -}}

これで、HugoサイトでGTMの呼び出しが可能となりました。

GTMでServiceWorker削除用のスクリプトを追加する

ワークスペースを新規に作成する

GTMの管理画面から、ワークスペースを追加します。

  1. Default Workspaceをクリック
  2. 右上の「+」マークを追加
  3. 「ServiceWorker削除ワークスペース」という名前をつけて「保存」

無料版では初期のDefault Workspaceと合わせて3つのワークスペースしか追加できません。今回はServiceWorkerの削除設定が正しく動作するのかを確認するためにワークスペースを専用に作成し、動作の確認が取れたら、Default Workspaceに統合します。

ワークスペースの追加

ServiceWorker削除ワークスペースServiceWorker削除用のタグを追加する

  1. 「タグ」をクリック
  2. 「新規」をクリック
  3. 「タグの設定」の中の「タグタイプを選択して設定を開始…」をクリック
  4. 「カスタム」の中の「カスタムHTML」を選択

します。HTMLには以下の中身を記載してみます。

カスタムHTML
1
2
3
4
5
6
<script>
caches.keys().then(function(keys){
    keys.forEach(function(cacheName) {
        console.log(cacheName);
    });});
</script>

次に

  1. 「トリガーの設定」の中の「トリガーを選択してこのタグを配信…」をクリック
  2. 「All Pages」を選択
  3. 「保存」を押して設定を反映

します。これで、ブラウザのコンソールに、サイトのキャッシュが存在するときにログとして表示するようになります。

GTMのプレビュー機能を利用して、動作を確認

確認のためにGTMのプレビュー機能を利用します。(※確認に利用するブラウザはGoogle Chromeとなります。)

プレビュー機能を利用すると、公開することなく現在の設定の確認が可能です。

  1. 画面の「プレビュー」をクリックします。
  2. 別タブが立ち上がったらGoogle Tag MangerをプレビューするサイトURLを入力します。
  3. 別ウィンドウでプレビュー画面が立ち上がります。

このままですとコンソール画面が表示されませんので、「右クリック」>「検証」、あるいは、【Command + Option + I(WindowsではCtrl+Shift+I)】を押してChromeデベロッパーツール(検証モード)を起動します。

設定がうまくいっており、キャッシュが残っている場合、【Console】タブに、キャッシュ名が表示されているはずです。今回は、cocoon_20190523_20210723224647

Chromeデベロッパーツール画面でキャッシュが残っていることを確認できる

ServiceWorkerの削除スクリプト

コンソールログで動作を確認できてたら、いよいよ設定を消し込みます。先ほどの「カスタムHTML」を以下のように設定変更します。

カスタムHTML
1
2
3
4
5
6
<script>
caches.keys().then(function(keys){
    keys.forEach(function(cacheName) {
        caches.delete(cacheName);
    });});
</script>

これでServiceWorkerの独自キャッシュが消えることになりますが、ServiceWorkerの登録は解除されません。そこで解除を試みることにします。

ServiceWorkerの登録解除スクリプト

先ほどの「カスタムHTML」を以下のように編集しなおします。

カスタムHTML
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
<script>
navigator.serviceWorker.getRegistrations().then(function(registrations) {
    for(var i = 0; i < registrations.length; i++){
    registrations[i].unregister();
  }
});
caches.keys().then(function(keys){
    keys.forEach(function(cacheName) {
        caches.delete(cacheName);
    });});
</script>

上半分がServiceWorkerの解除、下半分がキャッシュの削除となります。先ほどと同様、「プレビュー」にて動作を確認したら、「公開」をクリックします。 2022年3月21日時点でGTMではLoop構文が利用できないようですのでforと.lengthを利用することにしました。

なお、「公開」をクリックすると、先ほどまで操作をしていたServiceWorker削除ワークスペースDefault Workspaceに統合されます。Gitで言うと、ワークスペースがbranch、「公開」がmergeと考えるとわかりやすいかもしれません。

これでこのサイトにランディングしたユーザに対して、GTMでServiceWorkerの削除と登録解除が走ることになります。

設定にあたっては以下のサイトを参考にさせていただきました。

参考: