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
- You are familiar with responsive images.
- You have some familiarity with Hugo shortcodes.
- You are lazyloading images via lazysizes.
What this does
The following Hugo image shortcode does the following things:
- Processes an image into various sizes via Hugo Pipes
- Only generates images smaller than the original
- Prints your
src_set
into a string - 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:
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.