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

TIL
December 30, 2022

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;
}