HUGOテンプレートからSassに変数を渡す方法

Today I Learned

HUGO v0.109.0で追加された、HUGOテンプレートからSassに変数を渡す機能を試した。
HUGOにおけるSassの標準ライブラリであるLibSassでも利用できるが、if構文を使いたかったため、この記事ではDartSassを使用する。

要約

  • テンプレート:toCSSvarsオプションに、変数を定義したmapを渡す

    {{- $vars := ( dict "color1" "#1fb6ff" "color2" "#7e5bef" ) -}}
    {{- $opts := ( dict "transpiler" "dartsass" "vars" $vars ) -}}
    {{- $style := resources.Get "scss/main.scss" | toCSS $opts | fingerprint -}}
    
  • SCSS:渡された変数を使う箇所で@useして変数にアクセスする

    @use "hugo:vars" as h;
    
    .main {
      color: h.$color1;
    }
    
  • 設定ファイルに定義した変数も、SCSSに渡すことができる

動作を確認した環境

テンプレートファイルに変数を定義する場合

HUGO テンプレート

v0.109.0からtoCSSvarsオプションにmap(キーと値のペア)を渡せるようになった。
SCSS側では、varsに渡したmapの値にアクセスできる。

layouts/partials/head.html
{{- $vars := ( dict "color1" "#1fb6ff" "color2" "#7e5bef" ) -}}
{{- $opts := ( dict "transpiler" "dartsass" "vars" $vars ) -}}
{{- $style := resources.Get "scss/main.scss" | toCSS $opts | fingerprint -}}
{{ with $style }}<link rel="stylesheet" href="{{ .RelPermalink }}">{{ end -}}

SCSS

渡された変数を使う箇所で@use "hugo:vars as 名前空間"する。
@useでは名前空間を区切ることができるので、as 名前空間とすると、使うときに名前空間.変数名でアクセスできる。

assets/scss/main.scss
@use "hugo:vars" as h;

.main {
  color: h.$color1;
}

生成された CSS

hugoを実行して生成されたCSSを確認すると、HUGOテンプレートで渡した変数の値が注入されている。

public/scss/main.css
.main {
  color: #1fb6ff;
}

設定ファイルに変数を定義する場合

設定ファイルで切り替えているサイトごとに一部の色を変えたい場合など、設定ファイルに定義したCSSの変数を利用できる。

HUGO の設定ファイル

設定ファイルのParamsに、SCSSへ渡す変数(ここではstyle)を定義しているとする。
varsにはmapで渡す必要があるため、[params.変数名]のセクションにSCSSで使用する変数を定義する。

config.toml
[params.style]
colorTheme = "dark"
# var2 = ...

HUGO テンプレート

設定ファイルで設定した変数は$.Site.Params.変数名でアクセスできるので、これをvarsに渡す。

layouts/partials/head.html
{{- $opts := (dict "transpiler" "dartsass" "vars" $.Site.Params.style ) -}}
{{- $style := resources.Get "scss/main.scss" | toCSS $opts | fingerprint -}}
{{ with $style }}<link rel="stylesheet" href="{{ .RelPermalink }}">{{ end -}}

SCSS

SCSSの書き方は、テンプレートファイルに変数を定義する場合と変わらない。
DartSassは@ifで条件分岐ができるため、HUGOの設定ファイルで条件式のトリガーとなる変数を定義して、SCSS側で切り替えるような実装もできる。

assets/main.scss
@use "hugo:vars" as h;

$colorTheme: light !default;
$base-color: #fcfcfc !default;
$primary-text-color: #14171a !default;

@if h.$colorTheme == dark {
  $base-color: #15202b;
  $primary-text-color: #fefffe;
}

// メイン
.main {
  background-color: c.$base-color;
  color: c.$primary-text-color;
}

生成された CSS

生成されたCSSを確認すると、HUGOテンプレートで渡した変数の値が注入されている。

public/scss/main.css
.main {
  background-color: #15202b;
  color: #fefffe;
}