To insert an image in Hugo you write the standard Markdown , which renders as <img src "~">, but I had been wanting to build native lazy-load into the img tag.
Incidentally, native lazy-load means that
You can configure lazy loading of images easily just by adding the HTML loading attribute, without needing Javascript
At first I thought it could only be inserted by using the figure tag or a shortcut and went through some trial and error, but when I looked into it I learned that it becomes possible by using Hugo’s Render hooks.
If you want to know Render hooks in detail, see the official documentation.
Building in native Lazy load
Add the loading=“lazy’ attribute- Add the decoding=“async” attribute
I built in lazy at first, butdecoding="async" and loading="lazy" do not work together even when both are written, so I went with decoding="async".
When both are written, lazy takes precedence
Hugo/layouts/_defaults/_markup/render-image.html
{{ $link := string .Destination }}
{{ if hasPrefix $link "http" }}
<img decoding="async" src="{{ .Destination | safeURL }}" alt="{{ .Text }}" {{ with .Title}} title="{{ . }}"{{ end }} />
{{ else }}
<img decoding="async" src="{{ .Page.Permalink }}{{ .Destination | safeURL }}" alt="{{ .Text }}" {{ with .Title}} title="{{ . }}"{{ end }} />
{{ end }}Customizing the a link
- Links to external URLs open in a separate tab with target="_blank”
For security, noreferrer noopener is added as well - Internal links do not open a separate tab
Hugo/layouts/_defaults/_markup/render-link.html
<a href="{{ .Destination | safeURL }}"{{ with .Title}} title="{{ . }}"{{ end }}{{ if strings.HasPrefix .Destination "http" }} target="_blank" rel="noopener"{{ end }}>{{ .Text | safeHTML }}</a>Gist
I have also written these customizations down in a Gist