The following responsive image shortcode is based on Henrik Sommerfeld’s image shortcode. I originally had something close to Laura Kalbag’s method based on some tweaks by stereobooster, but I liked how Henrik’s shortcode avoided generating images you don’t need. His ouput for generating the src_set is also a little more dynamic/hands-off.

Assumptions

I make the following assumptions

What this does

The following Hugo image shortcode does the following things:

  1. Processes an image into various sizes via Hugo Pipes
  2. Only generates images smaller than the original
  3. Prints your src_set into a string
  4. Lazyloads the image via lazysizes.js

Some added features

  • Includes support for simple SVG src
  • Variable for inline CSS on the image, in case you need it
  • Adds contrast filter to LQIP image so the base64 output is smaller (generates a solid gray image). Remove this filter if you want a blurry LQIP placeholder image | images.Filter (images.Contrast -100).

The shortcode file

Name this file img.html and place it in layouts/shortcodes.

{{/*  Get shortcode variables  */}}
{{ $src := .Page.Resources.GetMatch (printf "*%s*" (.Get "src")) }}
{{ $alt := .Get "alt" }}
{{ $style := .Get "style" | safeCSS }}

{{/*  Checks if src file is an SVG. If not, continue...  */}}
{{ if strings.HasSuffix $src ".svg"}}
  <img class="lazyload" src="{{ $src.RelPermalink }}">
{{ else }}

  {{/*  Change "16x" width if your aspect ratio is different. The correct aspect ratio helps to prevent reflow.  */}}
  {{ $lqip := $src.Resize "16x"  | images.Filter (images.Contrast -100) }}
  {{ $img := imageConfig ($src.RelPermalink | printf "content/%s" ) }}
  {{ $src_set := ""}}
  {{ $src_set = (print $src.RelPermalink " " $src.Width "w") }}

  {{/*  Change small image size to your needs  */}}
  {{ if ge $src.Width "960" }}
  {{ $small := $src.Resize "960x" }}
  {{ $src_set = (print $src_set ", "  $small.RelPermalink " 960w") }}
  {{ end }}

  {{/*  Change medium image size to your needs  */}}
  {{ if ge $src.Width "1280" }}
  {{ $medium := $src.Resize "1280x" }}
  {{ $src_set = (print $src_set ", "  $medium.RelPermalink " 1280w") }}
  {{ end }}

  {{/*  Change large image size to your needs  */}}
  {{ if ge $src.Width "1920" }}
  {{ $large := $src.Resize "1920x" }}
  {{ $src_set = (print $src_set ", "  $large.RelPermalink " 1920w") }}
  {{ end }}

  {{/*  Change xlarge image size to your needs  */}}
  {{ if ge $src.Width "2048" }}
  {{ $xlarge := $src.Resize "2048x" }}
  {{ $src_set = (print $src_set ", "  $xlarge.RelPermalink " 2048w") }}
  {{ end }}

  {{/*  Add or remove additional sizes to suit your needs  */}}

  {{/*  remove this div if you need to  */}}
  <div class="img__wrap">

    {{/*  leave below as is  */}}
      <img
        class="lazyload"
        data-sizes="auto"
        src="data:image/jpeg;base64,{{ $lqip.Content | base64Encode }}"
        data-srcset="{{ $src_set }}"
        data-src="{{ $src.RelPermalink }}"
        width="{{ $img.Width }}"
        height="{{ $img.Height }}"
        alt="{{ $alt }}"
        {{ if $style}}style="{{ $style }}"{{ end }}
      />
  </div>

{{ end }}

Shortcode Usage

How you would use the shortcode in your markdown.

{{< img src="thumbnail.png" >}}

Shortcode in use:

Here’s the shortcode being used live:

test image

Output

Here’s the HTML output of the shortcode (just to show you):

<div class="img__wrap">
  <img
    class="lazyautosizes ls-is-cached lazyloaded"
    data-sizes="auto"
    src="/journal/efficient-image-shortcode/thumbnail.png"
    data-srcset="
      /journal/post/thumbnail.png 1280w,
      /journal/post/thumbnail_[fingerprint]_960x0_resize_lanczos_2.png 960w,
      /journal/post/thumbnail_[fingerprint]_1280x0_resize_lanczos_2.png 1280w"
    data-src="/journal/post/thumbnail.png"
    width="1280"
    height="720"
    alt="test image"
    sizes="821px"
    srcset="
      /journal/post/thumbnail.png 1280w,
      /journal/post/thumbnail_[fingerprint]_960x0_resize_lanczos_2.png 960w,
      /journal/post/thumbnail_[fingerprint]_1280x0_resize_lanczos_2.png 1280w
    "
  />
</div>

Efficient Responsive Image Shortcode

A hybrid shortcode solution for lazyloading, responsive images in Hugo without generating unnecessary images.