「サイトの文字フォントをオシャレなWebフォントに変更したい!」
「リッチなスクロールアニメーションや図解描画のためのJavaScriptライブラリを導入したい!」

Hugoで自作テーマを開発していると、このように外部から提供される便利な機能やアセットを取り入れたくなる場面が多くあります。
これらのライブラリを利用するには、基本的にHTMLの <head> タグ内や <body> の終了直前にスクリプトタグ等を追加する必要がありますが、今回はHugoにおいてそれらを「スマートに管理・読み込み」するための最適な手法を解説します。


1. Google Fonts の読み込み (CSS)

Google Fontsなどの外部CSSは、すべてのページに適用されるように ベーステンプレート (layouts/baseof.html)<head> 内に追加します。

手順

  1. Google Fontsのサイトで、使いたいフォントのEmbedコード(<link href="..."> )をコピーします。
  2. layouts/baseof.html を開きます。
  3. <head> タグの中に貼り付けます。
<!-- layouts/baseof.html -->
<head>
    <meta charset="UTF-8">
    <title>{{ .Title }} | {{ .Site.Title }}</title>
    
    <!-- ここに追加! -->
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@400;700&display=swap" rel="stylesheet">

    <link rel="stylesheet" href="{{ "css/style.css" | relURL }}">
</head>
  1. あとは static/css/style.css でフォントを指定すれば完了です。
body {
    font-family: 'Noto Sans JP', sans-serif;
}

2. 外部JavaScriptライブラリの読み込み

JavaScriptも基本は同じですが、読み込み位置や管理方法に少しコツがあります。

直接書き込む場合 (シンプル)

ページの動作に関わるスクリプト(Tocbotなど)は、</body> の直前に書くのが定石です。
これも layouts/baseof.html に追記します。

<!-- layouts/baseof.html -->
<body>
    <!-- ヘッダーやメインコンテンツ -->
    
    <footer>...</footer>

    <!-- ここに追加! -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/tocbot/4.18.2/tocbot.min.js"></script>
    <script>
        tocbot.init({
            tocSelector: '#TableOfContents',
            contentSelector: '.content',
            headingSelector: 'h2, h3',
        });
    </script>
</body>

3. 【推奨】Partialを使って整理整頓しよう

baseof.html に直接追記していくと、だんだんコードがごちゃごちゃして見づらくなってきます。
そこで、「読み込み専用の部品(Partial)」 を作って切り出すのがHugo流のスマートなやり方です。

手順

  1. layouts/partials/custom_head.html というファイルを作ります。
    • Note: 拡張子は必ずしも .html である必要はありませんが、エディタでHTMLとして認識させるために .html にするのが一般的です。custom_head.svg などにすることも可能です。
  2. その中に、Google Fontsなどのコードだけを書きます。
<!-- layouts/partials/custom_head.html -->
<link rel="preconnect" href="https://fonts.googleapis.com">
...
  1. layouts/baseof.html から、そのファイルを呼び出します。
<!-- layouts/baseof.html -->
<head>
    ...
    {{ partial "custom_head.html" . }}
</head>

こうしておけば、「外部ファイルの読み込み設定どこだっけ?」と迷うことがなくなります!
JavaScript用には custom_footer.html などを作ると良いでしょう。


4. 【上級編】必要なページだけ読み込む (パフォーマンス対策)

すべてのページで重いJavaScriptを読み込むと、サイトについて回る「重り」になってしまいます。
「使いたい記事だけ読み込む」 ように制御してみましょう。

例:Mermaid(図解ツール)の場合

  1. Front Matterでスイッチを作る
    記事の先頭で mermaid = true と書けるようにします。
+++
title = "私の記事"
mermaid = true
+++
  1. テンプレートで条件分岐する (layouts/partials/mermaid.html)
{{ if .Params.mermaid }}
  <script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
  <script>mermaid.initialize({ startOnLoad: true });</script>
{{ end }}
  1. baseof.html で読み込む
    mermaid.html を読み込みます。この中身は .Params.mermaid が true の時だけ出力されます。
{{ partial "mermaid.html" . }}
  1. 【重要】描画用の仕掛け (Render Hook)
    実は、これだけでは図が表示されません。Hugoが出力するHTMLと、Mermaidが期待するHTMLの形が少し違うからです。
    そこで、「mermaid という言語指定がされたら、Mermaid用のタグで囲む」という指示書(Render Hook)を作ります。

layouts/_markup/render-codeblock-mermaid.html を作成し、以下を記述します。
(※Hugo v0.145以前のバージョンでは layouts/_default/_markup/render-codeblock-mermaid.html に配置していました)

<div class="mermaid">
  {{ .Inner | safeHTML }}
</div>

これで、記事内に書いたコードが自動的に図として描画されるようになります!


Partialと条件分岐でスマートに外部ライブラリを管理しよう

フォントやアイコン、数式・図解描画ツールなど、便利な外部ライブラリはサイトの表現力を豊かにしてくれますが、何も考えずにすべてのページで読み込ませてしまうと、サイト全体の表示速度低下(パフォーマンス悪化)を招いてしまいます。
今回紹介した partial テンプレートによるコードの部品化と、{{ if .Params.xxx }} の条件分岐を活用して、「必要なアセットを、必要なページでのみ」ピンポイントで読み込むスマートなテーマ設計を心がけましょう!🚀