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 から乗り換えてみて、「自分のサイトのビルドくらいは自分で握る」のが一番気楽だ、という結論になった。フレームワーク不要論の、小さな実践。