Hugo 標準テンプレートで OGP・TwitterCard・Google Analytics を設定する
静的サイトジェネレーター Hugo には Template と呼ばれる仕組みでサイトのデザイン等の調整を行いますが、Internal Template として内部組み込みのテンプレートがいくつか用意されています。
Internal Template のページに書いてある通りなのですが、若干位置づけが読み取りづらかったので(どういう使い方で、どのレベルまで実現できるのか)、理解の補足用としてメモします。この記事では Google Analytics, OpenGraph (OGP), そして Twitter Card を設定します。
Internal Templates の内容
ドキュメントには以下の通り記載されています(2019/05/07 現在)。
_internal/disqus.html
_internal/google_news.html
_internal/google_analytics.html
_internal/google_analytics_async.html
_internal/opengraph.html
_internal/pagination.html
_internal/schema.html
_internal/twitter_cards.html
一方、これらを実現しているソースコードは GitHub の hugo/tpl/tplimpl/embedded/templates/
においてあります。
hugo/tpl/tplimpl/embedded/templates at master · gohugoio/hugo
Google Analytics
設定はシンプルで、テンプレートを一行組み込んだあとに(大部分のテーマでは標準で実装済みのようです)、 config.toml
で googleAnalytics = "UA-XXX"
を記載するのみ完了します。設定は baseURL
や theme
などの並びに書くようにしましょう。つい [params]
の下に書きがちですが、動きません。
ここで気になるのが google_analytics.html
と google_analytics_async.html
の違いです。asyn (非同期)の方を使っておけば間違いないだろうと想像するものの、一応裏付けとしてチェックしておきます。
--- ga 2019-05-07 12:16:20.000000000 +0900
+++ ga_async 2019-05-07 12:16:04.000000000 +0900
@@ -4,10 +4,7 @@
<script type="application/javascript">
{{ template "__ga_js_set_doNotTrack" $ }}
if (!doNotTrack) {
- (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
- (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
- m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
- })(window,document,'script','<https://www.google-analytics.com/analytics.js','ga>');
+ window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)};ga.l=+new Date;
{{- if $pc.UseSessionStorage }}
if (window.sessionStorage) {
var GA_SESSION_STORAGE_KEY = 'ga:clientId';
@@ -26,14 +23,6 @@
ga('send', 'pageview');
}
</script>
+<script async src='<https://www.google-analytics.com/analytics.js>'></script>
{{ end }}
{{- end -}}
-{{- define "__ga_js_set_doNotTrack" -}}{{/* This is also used in the async version. */}}
-{{- $pc := .Site.Config.Privacy.GoogleAnalytics -}}
-{{- if not $pc.RespectDoNotTrack -}}
-var doNotTrack = false;
-{{- else -}}
-var dnt = (navigator.doNotTrack || window.doNotTrack || navigator.msDoNotTrack);
-var doNotTrack = (dnt == "1" || dnt == "yes");
-{{- end -}}
-{{- end -}}
どう違うの?という質問はフォーラムにもありました(2016 年)。
Implementing Google Analytics in Hugo - support - Hugo Discussion
このページでリンクされているのか次のページ。
Make Google Analytics Asynchronous
ここで、以下の通り Apache or Nginx それぞれに設定しなければならない記載があります。
# Apache:
ModPagespeedEnableFilters make_google_analytics_async
# Nginx:
pagespeed EnableFilters make_google_analytics_async;
Nginx PageSpeed は Google が開発したレスポンス向上のための仕組みのようです。
試してみたいところですが Kubernetes の Ingress (Nginx) を利用しており、この Issue にてリクエストがあがっているものの実現されていないと思われる?(詳細未調査)
Support for Pagespeed · Issue #287 · kubernetes/ingress-nginx
一旦、自分の環境では作業保留しますが、Nginx を自由に弄れる環境ならば試したいところです。GitHub はこちら。
apache/incubator-pagespeed-ngx: Automatic PageSpeed optimization module for Nginx
OGP & Twitter Card の設定
OGP とか Twitter Card はただのリンクがリッチになる、SNS 等でよく見かけるあれです。
これらを実現するための meta
タグ設定は Internal Templates で実現できるようです。
自分でイチから書き起こす場合は The Open Graph protocol などを理解して作業しなければならないところですが、標準で準備されているのは有り難い。必要な情報は公式にまとまっているのですが(Internal Templates | Hugo)、Hugo に慣れていない時はこれだけだと戸惑います。おそらく、以下の点を抑えておけば実現できます。
設定方法 1. テーマの編集
大前提として、自身が利用しているサイトテーマ(Theme)によりファイル構造が異なるため、「どのファイルに修正を加える」という表現がこんなんです。<head>
を構成しているファイルに対して以下のコードを追加します。
<head>
~省略~
{{ template "_internal/opengraph.html" . }}
{{ template "_internal/twitter_cards.html" . }}
~省略~
</head>
Theme それぞれ条件が異なるものと理解してください。Theme によっては上記コードが含まれているものもありますので、重複設定にならないよう注意しましょう。
設定方法 2. 設定ファイルの編集
続いて config.toml
です。内容は公式に記載のとおりです。
[params]
description = "Text about my cool site"
images = ["site-feature-image.jpg"]
title = "My cool site"
[taxonomies] # この2行は意味がわからなければまだ
series = "series" # 利用していないということなので意識せず消してよい
ほか、マニュアルにある content/blog/my-post.toml
の例は、各記事で表示する個別の設定を行うものです。基本は以下の 3 項目を意識しておけばよいでしょう。
※動画・音楽などのメディア系のサイトの場合は、audio
や video
も重要になってくるはずです。
title = "Post title"
description = "Text about this post"
images = ["post-cover.png"]
記事の要約である description
は設定しなくても自動抽出してくれるのですが、日本語だと気持ちよく抽出してくれませんので、現時点は期待しないほうがいいと思います。そもそも要約はどう生成しているのかというと、以下の通りです。
If there is a summary divider present in the article the text up to the divider will be provided as per the manual summary split methodIf there is a summary variable in the article front matter the value of the variable will be provided as per the front matter summary methodThe text at the start of the article will be provided as per the automatic summary split method
- 各種ブログツールをはじめ定番の
<!-- more -->
のセパレータで分離して、それを要約として設定してくれる。 - Front-Matter (各記事の
.md
ファイル上部に書くdescription
の内容)を要約として設定 - 自動抽出
自動抽出は 3 番目で、config.toml
に summarylength = 10(例)
と書けば字数指定で抽出してくれるのですが、日本語等のマルチバイト文字だと(?)期待通りの動きになりません。原因未調査ですが、素直に 1 or 2 で意図的に設定した方がシンプルなので気にしないことにしました。
なお、この説明の順番を見ると Front-Matter (description
) よりも <!-- more -->
の方が強そうですが、両方設定した場合は Front-Matter の方が <head>
で使われます。この動きの方が自然でいいですね。
(注釈:この記事中では <!-- more -->
と記載していますが、正しくは more の両端にはスペースが入らない --more--
です。コードブロックで書いても本記事で反応してしまっているので回避のためスペースを挿入しています。)
config.toml 設定時に気をつけること
title = "My cool site"
この title
だけを見ると既に初期作業で設定していることが多いため、「あるからいいや」と思いがちなのですが、記載する部位が [params]
という欄(セクション?ディレクティブ?呼び方の理解が不十分なので、欄とします)に記載しなければなりません。理由は、og:site_name
を表示するためのコードが以下のようになっているためです。
{{- with .Site.Params.title }}<meta property="og:site_name" content="{{ . }}" />{{ end }}
したがって、config.toml
でのサイトタイトルの設定が複数登場することになります。おそらく以下のようになるでしょう。
title = "My cool site"
[params]
~省略~
title = "My cool site"
ほか、images
についても、最初は少々違和感がありました。
# こう設定することとなっているが
images = ["post-cover.png"]
# なぜこうじゃないのだろう?
image = "post-cover.png"
理由は以下の通り、それぞれが配列で渡されることを期待していて、1 つ目の要素をイメージとして設定しているためです。
/* opengraph.html の場合 */
{{ with $.Param "images" }}{{ range first 6 . }}
<meta property="og:image" content="{{ . | absURL }}" />
{{ end }}{{ end }}
/* twitter_card.html の場合 */
{{- with $.Params.images -}}
<meta name="twitter:card" content="summary_large_image"/>
<meta name="twitter:image" content="{{ index . 0 | absURL }}"/>
{{ else -}}
- opengraph.html#L5-L7
- twitter_cards.html#L1-L4
- TwitterCard では
images
がない場合にfeature
,cover
,thumbnail
といったキーを参照する分岐があるのですが、ここでは割愛します。
- TwitterCard では
ここまで、OpenGraph (OGP) と Twitter Cards の区別をしていませんでしたが、この設定で両者カバーできるので気にする必要はありません。
その他参考
toml
書き方で悩んだ時に、仕様はこちら。 toml-lang/toml: Tom’s Obvious, Minimal Language