2026年1月、ryus.dev のビルドを Go 製の自作 SSG(go-static-site)に移行した。2025年12月の first-go で Go を素振りしておいたので、その流れでそのまま本番に投入した。
中身
ライブラリは欲張らず、定番だけ。
- Markdown 変換: goldmark(GFM 拡張 + 見出し ID 自動付与)
- front matter: adrg/frontmatter
- テンプレート:
text/templateを//go:embedでバイナリに埋め込み
md := goldmark.New(
goldmark.WithExtensions(extension.GFM),
goldmark.WithParserOptions(parser.WithAutoHeadingID()),
goldmark.WithRendererOptions(html.WithUnsafe()),
)
//go:embed templates/*.html でテンプレートを埋め込んでいるので、バイナリ1つ(generate)だけ持っていけば動く。Node も依存ファイルも要らない。
機能
content/articles/{year}/*.mdを集めて HTML 生成- front matter(title / date / tags / description / draft)をパース
- 日付降順ソート、
draft: trueは除外 - 出力は
articles/{slug}/index.html
slug の取り方が地味に気に入っている。ファイル名の頭3つ(年・月・日)を落として、残りを slug にするだけ。
func (g *Generator) extractSlug(filename string) string {
parts := strings.SplitN(filename, "-", 4)
if len(parts) >= 4 {
return parts[3] // 2026-01-13-go-static-site-generator → go-static-site-generator
}
return filename
}
記事だけじゃなく docs/{category}/{slug}/ も同じ仕組みで吐けるようにしてある。
なぜ Go
- ビルドが速い
- 単一バイナリで CI から Node 依存を排除できる
- テンプレートも embed で同梱できる
学び
SSG は 本当に100行くらいで始められる。フレームワークを入れずに、goldmark + frontmatter + embed テンプレートを組むだけで、個人ブログには十分すぎる。Astro から乗り換えてみて、「自分のサイトのビルドくらいは自分で握る」のが一番気楽だ、という結論になった。フレームワーク不要論の、小さな実践。