これはなに

このサイトで使っているHugoのStackテーマをv3からv4へ移行したときに変更したり対応したりしたことのメモ。
主に下記の公式マイグレーション方法を参照した。
環境

- OS: Windows 11 Pro 25H2
- Hugo: v0.155.3 → v0.165.0
- hugo-theme-stack: v3.31.0 → v4.0.3
Hugoのバージョンを上げる

Stack v4はHugo v0.157.0以上が必要である。手元のバージョンはv0.155.3だったので上げる必要があった。今回は当時の最新版(v0.165.0)にした。
HugoのバイナリはHugoのGitHubリリースページから手に入る。
Stackはv3もv4も変わらず拡張バージョンのHugoが必要なので、extendedの付くバージョンをダウンロードする。ダウンロードしたファイルを解凍し、中身をパスを通してある場所に置く。筆者の場合はWindowsなので、C:\HugoExtended\binに置いて、環境変数PATHにC:\HugoExtended\binを追加している。
$ hugo version
hugo v0.165.0-76a5e1880ab46688155b02e99bab9be2a6134492+extended windows/amd64 BuildDate=2026-08-12T14:26:28Z VendorInfo=gohugoioこのサイトはNetlifyでホスティングしているので、Netlifyのビルド環境もHugo v0.165.0に上げる必要があった。
netlify.tomlでHUGO_VERSIONを指定している場合や、Netlify管理画面でHUGO_VERSIONの環境変数を指定している場合は、それも変更する。
Xのショートコードを修正する

これはStackテーマではなくHugoのバージョンを上げたことに起因する修正だが、Hugo組み込みのtweetショートコードはHugo v0.156で削除された。代わりにxショートコードを使うよう変更する。
- {{< tweet user="username" id="1234567890" >}}
+ {{< x user="username" id="1234567890" >}}
.Site.Dataをhugo.Dataに置き換える

これもHugoのバージョンを上げたことに起因する修正だが、Hugo組み込みの.Site.DataはHugo v0.156で非推奨となった。
代わりにhugo.Dataを使うよう変更する。
筆者の場合はカスタムで作っていたショートコードのurl-cardで.Site.Dataを使っていたため、置き換えた。
独自ファイルを退避する

v3からv4へ上げるに当たり、テーマ内の記述の仕方やファイルの切り方も変わっている。そのため、テーマを上書きするためにlayoutsやassetsを作っている場合は、それらを一時的に退避しておく。
このとき、ショートコード(v3ではlayouts/shortcodes)は、存在していないとビルドが成功しないので、移行にあたってビルドを成功させたいのであれば、ショートコードだけlayouts/_shortcodes/に移動する。
設定ファイルをマイグレーションする

v3でYAMLだった設定ファイルは、v4でTOMLを使うよう変更されている。HugoはYAMLを自動で変換してくれるためYAMLを使い続けても問題ないらしいが、結局設定を見直すことになるので、この機会にTOMLを使うことにした。
設定の書き方はhugo-theme-stack-starterが参考になる。Stackテーマのデモでもよい。StackのGetting Startedを見る限りhugo-theme-stack-starterは公式なテンプレートのようなので、今回はこれを参考にすることとした。config/_defaultディレクトリを作成し、下記ファイルを配置する。
config.toml

config.tomlには、サイトの基本情報を記述する。公式テンプレートから下記を変更した。
theme = "hugo-theme-stack"の記述を追加baseurlを自分のサイトのURLに変更localeおよびdefaultContentLanguageを日本語に変更。それに伴いhasCJKLanguageをtrueに変更
theme = "hugo-theme-stack"の記述が必要。Hugo Moduleで管理しているなら、themeは不要となる。変更後のconfig.toml
theme = "hugo-theme-stack"
baseurl = "https://notes.nakurei.com/"
locale = "ja-JP"
title = "NakuRei's Notes"
copyright = "NakuRei"
# Theme i18n support
# See all available values at https://github.com/CaiJimmy/hugo-theme-stack/tree/master/i18n
defaultContentLanguage = "ja"
# Set hasCJKLanguage to true if DefaultContentLanguage is in [zh-cn ja ko]
# This will make .Summary and .WordCount behave correctly for CJK languages.
hasCJKLanguage = true
enableRobotsTXT = true
enableGitInfo = true
timeout = "300s"
[services.googleAnalytics]
ID = "G-XXXXXXXXXX"
[pagination]
pagerSize = 10
[frontmatter]
lastmod = ["lastmod", ":git", "date", "publishDate"]languages.toml

languages.tomlには多言語対応の設定を記述する。この設定項目はv3のlanguagesと同じである。
_languages.tomlとなっているが、これは設定を反映させないためにアンダーバーを付けている。よってこれを設定する場合は、アンダーバーを削除したlanguages.tomlとして作成する。変更後のlanguages.toml
[ja]
label = "日本語"
locale = "ja"
weight = 1
[ja.params]
description = "努力の積み重ねを記録しておくためのサイト。"
[ja.params.sidebar]
subtitle = "努力の積み重ねを記録しておくだけ"
[en]
label = "English"
locale = "en"
weight = 2
[en.params]
description = "A website to keep track of my efforts."
[en.params.sidebar]
subtitle = "Just keep track of my efforts."markup.toml

markup.tomlにはMarkdownのレンダリングに関する設定を記述する。v3のときにmarkupで設定していた内容と変更はない。素直に移植できる。
変更後のmarkup.toml
# Markdown renderer configuration
[goldmark.renderer]
unsafe = false
[goldmark.extensions.passthrough]
enable = true
[goldmark.extensions.passthrough.delimiters]
block = [['\[', '\]'], ['$$', '$$']]
inline = [['\(', '\)']]
[tableOfContents]
endLevel = 4
ordered = true
startLevel = 2
[highlight]
noClasses = false
codeFences = true
guessSyntax = true
lineNoStart = 1
lineNos = false
lineNumbersInTable = true
tabWidth = 4menu.toml

menu.tomlにはメインメニューとSocialメニューの設定を記述する。このサイトではSocialメニューしか設定を記述していないが、Socialメニューに限れば、設定項目はv3のときと同じだった。
変更後のmenu.toml
[[social]]
identifier = "github"
name = "GitHub"
url = "https://github.com/NakuRei"
[social.params]
icon = "brand-github"
[[social]]
identifier = "x"
name = "X"
url = "https://x.com/nakurei7901"
[social.params]
icon = "brand-twitter"
[[social]]
identifier = "rss"
name = "RSS"
url = "https://notes.nakurei.com/index.xml"
[social.params]
icon = "rss"
[[social]]
identifier = "zenn"
name = "Zenn"
url = "https://zenn.dev/nakurei"
[social.params]
icon = "link"module.toml

module.tomlにはHugo Moduleの設定を記述する。今回はHugo ModuleではなくGit Submoduleで管理しているので、module.tomlは作成しない。
params.toml

params.tomlにはサイト全体のパラメータを記述する。v3のときにparamsで設定していた内容である。v4では下記paramsが変更されている。
dateFormatの書き方が、Jan 02, 2006のようなGoのフォーマット文字列から、:date_fullや:date_mediumのようなHugoのフォーマット文字列に変更されたSortByが追加されたfeaturedImageFieldが廃止された: v4ではimage固定となったdefaultImage.opengraphが廃止された
変更後のparams.toml
# Pages placed under these sections will be shown on homepage and archive page.
mainSections = ["post"]
# Output page's full content in RSS.
rssFullContent = true
favicon = "img/favicon.png"
# Accepted values: "default", "lastmod"
# default = see https://gohugo.io/quick-reference/glossary/#default-sort-order
# lastmod = sort by last modified date, in descending order
SortBy = "lastmod"
[author]
name = "NakuRei"
url = "https://notes.nakurei.com/"
[footer]
since = 2022
customText = ""
[dateFormat]
published = ":date_medium"
lastUpdated = ":date_medium"
[sidebar]
compact = false
emoji = "🐢"
subtitle = ""
avatar = "img/avatar.png"
[article]
headingAnchor = true
math = false
toc = true
readingTime = true
[article.license]
enabled = true
default = "Licensed under CC BY-NC-SA 4.0"
[widgets]
homepage = [
{ type = "search" },
{ type = "categories", params = { limit = 10 } },
{ type = "tag-cloud", params = { limit = 10 } },
{ type = "archives", params = { limit = 5 } },
]
page = [
{ type = "toc" },
{ type = "categories", params = { limit = 10 } },
{ type = "tag-cloud", params = { limit = 10 } },
]
[opengraph.twitter]
site = "nakurei7901"
card = "summary_large_image"
[colorScheme]
toggle = true
default = "auto"
## Comments
[comments]
enabled = false
provider = "disqus"
# See all the available configurations at https://github.com/CaiJimmy/hugo-theme-stack/blob/master/config/_default/params.toml
# Copy the configurations you need from there and paste it here.
## Original url-card shortcode
defaultNoImage = "icons/photo-off.svg"
defaultNoLinkImage = "/icons/link-off.svg"
imageQuality = 80permalinks.toml

permalinks.tomlはv3のときにpermalinksで設定していた内容と同じ内容を設定する。特に新しい設定項目はない。
変更後のpermalinks.toml
post = "/post/:slug/"
page = "/:slug/"related.toml

related.tomlはv3のときにrelatedで設定していた内容と同じ内容を設定する。特に新しい設定項目はない。
変更後のrelated.toml
# Related contents configuration
includeNewer = true
threshold = 60
toLower = false
indices = [
{ name = "tags", weight = 100 },
{ name = "categories", weight = 200 },
]faviconを移動する

faviconとavatarの画像は、v3ではstatic/に置いていたが、v4ではassets/に置くよう変更されている。このサイトではavatarはassets/img/に配置していたが、faviconはstatic/img/に置いていたので、faviconの画像をassets/img/に移動した。
ページのフロントマターを修正する

v3からv4では、記事のフロントマターに変更があった。v3ではhiddenだったが、v4ではbuild.listに変わった。よって、hidden = trueを指定していた場合は、下記のようにbuild.listをneverに変更する必要がある。
---
- hidden: true
+ build:
+ list: never
---
hidden = falseを指定していた場合は、build.listをalwaysに指定する。
---
- hidden: false
+ build:
+ list: always
---
レイアウトのカスタムをマイグレーションする

Hugoではテーマと同じ位置に同じ名前のファイルを置くことでテーマのファイルを上書きできる。 Stackテーマはv3からv4になるタイミングで、テーマ内の記述の仕方やファイルの切り方も変わっている。 そのため、テーマをカスタムしていた場合は、v4に合わせてカスタムしたファイルを正しい配置や名前、内容に修正する。
layouts/_default/の中身をlayouts/へ移動する

Hugo v0.146.0でModern Template Systemが導入されたことで、layouts/_default/フォルダを利用した管理は非推奨となり、layouts/直下への配置に統合された。
Stackテーマもそれに習い、v4ではlayouts/_default/の中身をlayouts/へ配置するよう変更されている。
よって、layouts/_default/を使っていた場合はlayouts/へ移動する。
筆者の場合は、テーマのlayouts/_default/_markupを改変していたので、layouts/_default/_markupをlayouts/_markupへ移動した。
layouts/partialsの中身をlayouts/_partialsへ移動する

これもHugo v0.146.0でModern Template Systemが導入されたことに起因する変更である。
Stack v4はこれに従いlayouts/partialsからlayouts/_partialsへ変更している。
よって、テーマをカスタムしていた場合は、layouts/partialsの中身をlayouts/_partialsへ移動する必要がある。
ヘッダー画像の高さを変える

Stack v4では、ヘッダー画像の高さをassets/scss/custom.scssで変更できるようになった1。デフォルトはモバイルで150px、中間が200px、大画面で250pxとなっている。
筆者はv3の時点で、モバイルで100px、中間で150px、大画面も150pxにカスタムしていたので、assets/scss/custom.scssを作成して下記を記載した。
:root {
--article-image-height: 100px;
@include respond(md) {
--article-image-height: 150px;
}
@include respond(xl) {
--article-image-height: 150px;
}
}var(--zh-font-family)を削除する

このサイトではv3の時点でCSSをカスタムしてフォントを変えていたが、Stack v4ではvar(--zh-font-family)が削除されたため、そのままだと設定が無視されるという問題が生じた。よってvar(--zh-font-family)を削除した。CSS変数の未定義参照はプロパティ全体が無効になるので、削除するだけでカスタムは有効に戻った。
参考文献・URL

Stack v3では、
assets/scss/partials/article.scssを上書きして変更する必要があったので、個人的にはありがたい変更。 ↩︎


