Cherry pick from fonts.googleapis.com in config.toml

Customized google fonts was adressed by @Hash_Borgir quite a time ago Forum: How To
Dynamically Use Google Fonts In A Hugo Website

I like to keep things configurable (in config.toml). This includes the
font-family. I use fonts.googleapis.com to cherry pick some fonts from
https://fonts.google.com .

This is probably not for people using pre or post processors in their tool
chain - but others may be inspired by the following:

Here are the predefined generic font names

  • sans-serif
  • serif
  • monospace
  • cursive
  • fantasy

In order to include the following in the pages:

<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Nova+Slim|Nova+Mono" />
<style> html {font-family: 'Nova Slim', cursive; } </style>
<style> body {font-family: 'Nova Slim', cursive; } </style>
<style> h1 {font-family: 'Nova Slim', cursive; } </style>
<style> h2 {font-family: 'Nova Slim', cursive; } </style>
<style> h3 {font-family: 'Nova Slim', cursive; } </style>
<style> h4 {font-family: 'Nova Slim', cursive; } </style>
<style> h5 {font-family: 'Nova Slim', cursive; } </style>
<style> h6 {font-family: 'Nova Slim', cursive; } </style>
<style> pre {font-family: 'Nova Mono', monospace; } </style>
<style> code {font-family: 'Nova Mono', monospace; } </style>

a config.toml would include:

[params.googleApiFonts.family]
  tagsText        = [ "html", "body" ]
  tagsHeading     = [ "h1", "h2", "h3", "h4", "h5", "h6" ]
  tagsMono        = [ "pre", "code" ]
  fallbackText    = "html"
  fallbackHeading = "html"
  fallbackMono    = "pre"

[params.googleApiFonts.family.html]
  cursive    = "Nova Slim"
[params.googleApiFonts.family.pre]
  monospace  = "Nova Mono"

There are 3 “siblings” - text, heading and mono.
For each one (text, heading, mono) there is a fall-back defined which is used if
no configuration is given.

Do not use too many fonts - visitors end up in longer loading times and it looks
"bad" :nerd_face: . But just to show the idea - here’s another example:

[params.googleApiFonts.family]
  tagsText        = [ "html", "body", "time" ]
  tagsHeading     = [ "h1", "h2", "h3", "h4", "h5", "h6" ]
  tagsMono        = [ "pre", "code", "samp" ]
  fallbackText    = "html"
  fallbackHeading = "h1"
  fallbackMono    = "pre"

[params.googleApiFonts.family.html]
  sans-serif = "Poppins"
[params.googleApiFonts.family.time]
  cursive    = "Creepster"
[params.googleApiFonts.family.h1]
  sans-serif = "Days One"
[params.googleApiFonts.family.h3]
  cursive    = "Creepster"
[params.googleApiFonts.family.pre]
  monospace  = "Cousine"
[params.googleApiFonts.family.samp]
  sans-serif = "Roboto"
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Poppins|Creepster|Days+One|Cousine|Roboto" />
<style> html {font-family: 'Poppins', sans-serif; } </style>
<style> body {font-family: 'Poppins', sans-serif; } </style>
<style> time {font-family: 'Creepster', cursive; } </style>
<style> h1 {font-family: 'Days One', sans-serif; } </style>
<style> h2 {font-family: 'Days One', sans-serif; } </style>
<style> h3 {font-family: 'Creepster', cursive; } </style>
<style> h4 {font-family: 'Days One', sans-serif; } </style>
<style> h5 {font-family: 'Days One', sans-serif; } </style>
<style> h6 {font-family: 'Days One', sans-serif; } </style>
<style> pre {font-family: 'Cousine', monospace; } </style>
<style> code {font-family: 'Cousine', monospace; } </style>
<style> samp {font-family: 'Roboto', sans-serif; } </style>

The relevant partial is here:

{{- if isset $.Site.Params (lower "googleApiFonts") }}
  {{- if isset $.Site.Params.googleApiFonts (lower "family") }}
    {{- if $.Site.Params.googleApiFonts.family }}

      {{- $myStyleTagsText    := $.Site.Params.googleApiFonts.family.tagsText }}
      {{- $myStyleTagsHeading := $.Site.Params.googleApiFonts.family.tagsHeading }}
      {{- $myStyleTagsMono    := $.Site.Params.googleApiFonts.family.tagsMono }}
      {{- $myStyleTags        := union $myStyleTagsText (union $myStyleTagsHeading $myStyleTagsMono) }}

      {{- $myStyleTagFallbackText    := $.Site.Params.googleApiFonts.family.fallbackText | default "html" }}
      {{- $myStyleTagFallbackHeading := cond (isset $.Site.Params.googleApiFonts.family (lower "fallbackHeading") ) $.Site.Params.googleApiFonts.family.fallbackHeading  "html" }}
      {{- $myStyleTagFallbackMono    := cond (isset $.Site.Params.googleApiFonts.family (lower "fallbackMono"   ) ) $.Site.Params.googleApiFonts.family.fallbackMono     "html" }}

      {{- range $se := $myStyleTags }}
        {{- if index $.Site.Params.googleApiFonts.family $se }}
          {{- range (index $.Site.Params.googleApiFonts.family $se ) }}
            {{- if . }}
              {{- if not (in ($.Scratch.Get "family") (printf "%s|" (trim . " ") )  ) }}
                {{- $.Scratch.Set "family" (printf "%s|%s" ($.Scratch.Get "family" | default "" ) (trim . " ") ) }}
              {{- end }}
            {{- end }}
          {{- end }}
          {{- $.Scratch.Set "family" ((strings.TrimPrefix "|" ($.Scratch.Get "family") ) | replaceRE ` ` "+") }}
        {{- end }}
      {{- end }}

      {{- if  $.Scratch.Get "family" }}
        {{- $myHref := (printf `href="%s%s"` "https://fonts.googleapis.com/css?family=" ($.Scratch.Get `family`) )  }}
  <link rel="stylesheet" {{$myHref | safeHTMLAttr}} />
      {{- else }}
        {{/* no font names found ... */}}
      {{- end }}

      {{- template "googleapis.font-family" (dict "family" $.Site.Params.googleapifonts.family "tags" $myStyleTagsText    "fallback" $myStyleTagFallbackText   ) }}
      {{- template "googleapis.font-family" (dict "family" $.Site.Params.googleapifonts.family "tags" $myStyleTagsHeading "fallback" $myStyleTagFallbackHeading) }}
      {{- template "googleapis.font-family" (dict "family" $.Site.Params.googleapifonts.family "tags" $myStyleTagsMono    "fallback" $myStyleTagFallbackMono   ) }}

    {{- end }} {{/* $.Site.Params.googleApiFonts.family */}}
  {{- end }} {{/* family */}}
{{- end }} {{/* googleApiFonts */}}


{{- define "googleapis.font-family" }}
  {{- $theGoogleApiFontsFamily := index . "family"   }}
  {{- $theStyleTags            := index . "tags"     }}
  {{- $theStyleTagFallback     := index . "fallback" }}

  {{- range $se := $theStyleTags }}
    {{- if index $theGoogleApiFontsFamily  $se }}
  <style> {{$se}} {
      {{- range $g, $f := (index $theGoogleApiFontsFamily $se ) -}}
        {{- if . }}font-family: '{{$f}}', {{$g}}; {{ end }}
      {{- end -}} } </style>
    {{- else }}
  <style> {{$se}} {
      {{- if index $theGoogleApiFontsFamily $theStyleTagFallback }}
        {{- range $g, $f := (index $theGoogleApiFontsFamily $theStyleTagFallback ) }}
          {{- if . }}font-family: '{{$f}}', {{$g}}; {{ end }}
        {{- end }}
      {{- end -}} } </style>
    {{- end }}
  {{- end }}
{{- end}}

Feel free to adapt, improve, simplify, …
Here’s my current version head.fonts.googleapis.html

3 Likes

Hi, thanks for adapting my post. I love your adaptation. I was thinking about putting the selectors and elements in the config myself but had not done so because my template doesn’t change. I took and modified the hugo-universal-theme for Psychedelics Daily.

I’m in the middle of rebuilding my blog design so https://stoned.io is down right now.

The previous post in which I discussed this, I only linked to the post on how I did it on my blog, and since my blog is down, let me quickly share what I originally did, in case someone needs that for reference material.

In /config.toml

/config.toml

[params.font]
    # Some example fonts: Domine, Raleway, "Gentium Basic", Lato

    body = "Lato"
    heading = "Raleway"
    blockquote = "Gentium Basic"
    nav = "Domine"
    paragraph = "Roboto"

Where ever you have your <head></head> tags, in that partial template, right before the closing </head> tag, insert something like:

<!-- Google fonts -->
<link lazyload="1" href='//fonts.googleapis.com/css?family=Roboto:400,100,100italic,300,300italic,500,700,800|{{ .Site.Params.font.body }}|{{ .Site.Params.font.heading }}|{{ .Site.Params.font.blockquote }}|{{ .Site.Params.font.nav }}|{{ .Site.Params.font.paragraph }}' rel='stylesheet' type='text/css'>

<style>
body {
    font-family: '{{ replace .Site.Params.font.body "+" " "}}';
}

h1, h2, h3,
h4, h5, h6 {
    font-family: '{{ replace .Site.Params.font.heading "+" " "}}';
}

blockquote {
    font-family: '{{ replace .Site.Params.font.blockquote "+" " "}}';

}
.dropdown a {
    font-family: '{{ replace .Site.Params.font.nav "+" " "}}'

}
.post-content p {
    font-family: '{{ replace .Site.Params.font.paragraph "+" " "}}'
}
</style>

Be sure to change the CSS selectors to what you need per your design.

This is basically how I control changing fonts across my entire site from simply modifing config.toml.

Thanks for Hugo. It’s amazing! :slight_smile:

1 Like