HugoのDocsyテーマを使いながら、SEOやテンプレートまわりで工夫した点の記録です。
テーマを直接編集しない
Docsyテーマを使っていましたが、テーマのファイルを直接編集するのは避けていました。バージョンアップのたびに手動マージが発生するからです。Docsyは更新頻度が高く、partialの構成がバージョンで変わることもあるので、直接触ると面倒が増えます。
HugoにはLookup Orderがあり、layouts/ に置いたファイルが themes/ より優先されます。上書きしたい部分だけ layouts/ に配置すれば、テーマ本体は触らなくて済みます。
この方針でやっていたカスタマイズをいくつか紹介します。
noindexの設計判断
Docsyのデフォルトでは、本番ビルド時にすべてのページに <meta name="robots" content="index, follow"> が付きます。タグ一覧やセクションページまでインデックスされるのは気持ち悪かったので、制御を入れました。
layouts/partials/head.html を上書きし、robotsのロジックだけを layouts/partials/noindex.html に分離しました。
{{ if or (eq .Params.Noindex true) (eq .Kind "section") (eq .Section "tags") }}
<meta name="robots" content="noindex, nofollow">
{{ else }}
{{ if hugo.IsProduction }}
<meta name="robots" content="index, follow">
{{ end }}
{{ end }}
ポイントは3つです。
- FrontMatterでの個別制御: 記事単位で
noindex: trueを指定できる - セクションページの一括noindex: 記事一覧はインデックス不要と判断
- タグページのnoindex: 自動生成のタグ一覧は内容が薄い
head.html 全体をコピーせず、robotsのロジックだけpartialに切り出しています。テーマのhead.htmlが更新されても影響を受けにくいです。
構造化データ
JSON-LD形式の構造化データを入れました。Google検索結果に公開日・更新日を出すためです。
{
"@type": "BlogPosting",
"datePublished": "2022-11-06T00:00:00+09:00",
"dateModified": "2022-11-06T00:00:00+09:00"
}
Goの日付フォーマットは独特で、参照日時 2006-01-02T15:04:05 をテンプレートとして使います。最初は少し戸惑いました。
Google検索セントラルには「1つの日付要素だけに依存すると問題が生じやすい」とあるので、JSON-LDに加えて記事本文にも「YYYY年MM月DD日公開」を入れています。
minifyハック — IE Conditional Commentsの目的外利用
これは正直、ハックと呼ぶしかない対応でした。
Googleのモバイル検索結果にサムネイル画像を表示するために、PageMapデータをHTMLに埋め込む必要がありました。問題は、PageMapデータはHTMLコメント内に記述する仕様だということです。
<!--
<PageMap>
<DataObject type="thumbnail">
<Attribute name="src" value="https://example.com/image.jpg"/>
</DataObject>
</PageMap>
-->
ところが hugo --minify を使うとHTMLコメントがすべて消えます。minify全体を無効にするのも嫌なので、別の方法を探しました。
Hugoが内部で使っているminifyライブラリ(tdewolff/minify)に keepConditionalComments: true というオプションがありました。IE Conditional Commentsだけは残す設定です。
IE Conditional Commentsの [if true](常にtrue)を使えば、minify有効のままコメントを残せます。
{{"<!--[if true]>" | safeHTML}}
<PageMap>
<DataObject type="thumbnail">
<Attribute name="src" value="{{ $metaThumbnailImage | absURL }}"/>
</DataObject>
</PageMap>
{{"<![endif]-->" | safeHTML}}
IEのサポートは終了しているので実害はありません。ただ、Googleのクローラーがこの形式を正しく解釈する保証もないので、 <meta name="thumbnail"> タグとの併用を前提にしています。
まとめ
Lookup Orderを使ってテーマ本体に手を入れない方針にしておくと、テーマ更新が楽です。minifyハックは力技でしたが、ライブラリの実装を読んで回避策を逆引きするアプローチ自体は割と汎用的でした。

![[ポートフォリオサイト制作] 静的サイトジェネレーター Hugo での作成手順](/tcard/8637a8a2-55fc-4ba3-96b9-3e8c4b70c00c/2022-12-13-8637a8a2-55fc-4ba3-96b9-3e8c4b70c00c.webp)
![Notion を Hugo のヘッドレスCMSとして利用する方法 [Notion Hugo Exporter]](/tcard/notion-hugo-exporter-getting-started/2022-12-03-notion-hugo-exporter-getting-started.webp)