Search code examples
htmlhugohugo-shortcode

Changing Hugo's built-in figure shortcode to add lazy loading to images


In my Hugo-generated website I'm making use of the built-in shortcode figure. Example:

{{< figure src="myImage.svg" width="100%" alt="Some description" >}}

This renders the following HTML:

<figure>
    <img src="myImage.svg"
         alt="Some description" width="100%"/> 
</figure>

But now I'm trying to update my Hugo website in such way that the figure shortcode adds the loading=lazy attribute to the img tag:

<figure>
    <img 
         loading="lazy"
         src="myImage.svg"
         alt="Some description" width="100%"/> 
</figure>

How can I achieve my goal of letting images be loaded lazily using the (new) loading attribute?


Solution

  • You can create a file named layouts\shortcodes\figure.html and copy the contents of Hugo's figure shortcode source code into this file. Here's the current source code:

    <figure{{ with .Get "class" }} class="{{ . }}"{{ end }}>
        {{- if .Get "link" -}}
            <a href="{{ .Get "link" }}"{{ with .Get "target" }} target="{{ . }}"{{ end }}{{ with .Get "rel" }} rel="{{ . }}"{{ end }}>
        {{- end -}}
        <img src="{{ .Get "src" }}"
             {{- if or (.Get "alt") (.Get "caption") }}
             alt="{{ with .Get "alt" }}{{ . }}{{ else }}{{ .Get "caption" | markdownify| plainify }}{{ end }}"
             {{- end -}}
             {{- with .Get "width" }} width="{{ . }}"{{ end -}}
             {{- with .Get "height" }} height="{{ . }}"{{ end -}}
        /><!-- Closing img tag -->
        {{- if .Get "link" }}</a>{{ end -}}
        {{- if or (or (.Get "title") (.Get "caption")) (.Get "attr") -}}
            <figcaption>
                {{ with (.Get "title") -}}
                    <h4>{{ . }}</h4>
                {{- end -}}
                {{- if or (.Get "caption") (.Get "attr") -}}<p>
                    {{- .Get "caption" | markdownify -}}
                    {{- with .Get "attrlink" }}
                        <a href="{{ . }}">
                    {{- end -}}
                    {{- .Get "attr" | markdownify -}}
                    {{- if .Get "attrlink" }}</a>{{ end }}</p>
                {{- end }}
            </figcaption>
        {{- end }}
    </figure>
    

    After that you can make the required changes to your local figure.html. For instance:

    ...
        <img src="{{ .Get "src" }}" loading="lazy" decoding="async"
    ...
    

    Hugo prefers your locally defined shortcode over its built-in version, meaning that this overrides the built-in behavior.