Hugoで日本語のページ内リンクが正常に動かない問題の解決方法

これはなに Link to this heading

静的サイトジェネレーターHugoで、ページ内リンクが日本語の際にうまく動作しない問題について解説し、その解決方法を述べる。

発生した問題 Link to this heading

Hugoを使用して、本文中で日本語の小見出しをリンク参照したい場合に、次のように記述する。

[発生した問題](#発生した問題)

こうすることで、クリックして小見出しを参照できるリンクが生成されるはずである。 しかし、筆者の環境では、このリンクが正常に動作しなかった。

問題の原因 Link to this heading

この問題は、Hugoがリンクのアンカータグ(タグ)を生成する際に、日本語の文字列を正しく扱えていないことが原因である。Hugoは、ページ内リンクのアンカータグを生成する際に、リンク先の見出しのテキストを元にID属性を付与し、そのID属性に基づいてaタグのhref属性を生成する。このとき、生成されたaタグのhref属性がエンコードされてしまったため、リンクが正常に動作しなかった。

つまり、筆者の環境で日本語を含むリンクがエンコードされてしまうことが問題の原因だった。

解決方法の実行 Link to this heading

この問題を解決するために、リンクを貼った際にエンコードしないように設定した。 まず、元のテーマからlayouts/_default/_markup/render-link.htmlをコピーする。

cp ./themes/hugo-theme-stack/layouts/_default/_markup/render-link.html ./layouts/_default/_markup/

元のファイルでは、次のように記述されていた。

render-link.html
<a class="link" href="{{ .Destination | safeURL }}" {{ with .Title}} title="{{ . }}"
    {{ end }}{{ if strings.HasPrefix .Destination "http" }} target="_blank" rel="noopener"
    {{ end }}>{{ .Text | safeHTML }}</a>

このhref="{{ .Destination | safeURL }}"を、{{ printf "href=%q" .Destination | safeHTMLAttr }}に変更する。変更後の記述は次のようになる。

render-link.html
<a class="link" {{ printf "href=%q" .Destination | safeHTMLAttr }}
    {{ with .Title}} title="{{ . }}"{{ end }}
    {{ if strings.HasPrefix .Destination "http" }} target="_blank" rel="noopener"
    {{ end }}>{{ .Text | safeHTML }}</a>

{{ printf "href=%q" .Destination | safeHTMLAttr }}にすることで、日本語の文字列がエンコードされずにhref属性へ設定される。これにより、日本語のページ内リンクが正常に動作するようになる。

まとめ Link to this heading

この記事では、Hugoで日本語のページ内リンクが正常に動作しない問題とその解決方法を紹介した。問題の原因は、Hugoが日本語の文字列を正しく扱えないことであり、layouts/_default/_markup/render-link.htmlhref属性の設定を変更することで解決した。Hugoを使用して日本語のページ内リンクを設定する際にお悩みの方は、ぜひこの解決方法を試してみてほしい。

参考文献・URL Link to this heading

Licensed under CC BY-NC-SA 4.0
最終更新 5月 21, 2023
Hugo で構築されています。
テーマ StackJimmy によって設計されています。