How to resize/downscale images

An article with lots of images embedded like this ![]() currently puts all the images in their full resolution in the article, wasting a lot of bandwidth.

How do I change my theme so that ![]() renders a downscaled version of the image with a link to its full resolution?

One option is to have two sets of images: original and resized. Then you could create a shortcode, say it’s named img.html:

{{- $resizedURL := .Get "resizedURL" -}}
{{- $originalURL := .Get "originalURL" -}}
{{- $alt := .Get "alt" -}}
{{- $class := .Get "class" -}}
{{- $style := .Get "style" -}}

<a href="{{ $originalURL | relURL }}"><img src="{{ $resizedURL | relURL }}" alt="{{ $alt }}" class="{{ $class }}" style="{{ $style | safeCSS }}"></a>

Then use it like:

{{< img resizedURL="img/some-img.png" originalURL ="img/some-img.png" alt="Some description" class="some-class" style="some-style" >}}

alt, class, and style arguments would be optional


Another option is to use Hugo Image Processing. I’m not familiar with this myself, so someone else would have to help you there.

I’m trying to avoid the shortcode. Is there a way to hook into the rendering of the ![]() tag?

Also in your example it looks like I need to supply the resized image myself. I would like Hugo to create the downscaled version autoatically.

Not that I know of

Checkout the Image Processing docs I linked previously

The only thing that I can think of that will do what you want is one that I do not recommend doing.

Basically, do a massive find and replace on the content of the page, doing something like the following:

  • Use regex to find every image in .Content
  • Parse the image tag to find the source of the image
  • If the image exists in the assets/ folder or the page bundle, continue
  • Create a Hugo asset out of the image, for processing
  • Use Hugo’s built-in image processing to shrink the image
  • Replace the original image tag with a new one using the smaller image, wrapped in a link to the original file

It’s a really hackish way to do it and is more likely to cause issues. The more sustainable option is to make a shortcode like @zwbetz suggested. But what you want to do is technically possible.

Thank you @zwbetz and @Shadow53. This is my current solution:

File /layouts/shortcodes/img.html:

{{ $original := .Page.Resources.GetMatch (.Get 0) }}
{{ $preview := $original.Resize "636x" }}
{{ $alt := .Get 1 }}

{{ if lt $original.Width 636 }}
<img src="{{ $original.RelPermalink }}" width="{{ $original.Width }}" alt="{{ $alt }}">
{{ else }}
<a href="{{ $original.RelPermalink }}" target="_blank" title="{{ $alt }}">
	<img src="{{ $preview.RelPermalink }}" width="{{ $preview.Width }}" alt="{{ $alt }}">
</a>
{{ end }}

And in my article:

{{< img myimagefile "Alternative text" >}}

This works really well, the images can even be included withithout paths and it works on the front page. Awesome.

However, I’m still interested if I can get Hugo to read Markdown style images ![](). I tried replaceRE within the theme, but the content is already in HTML. Is there a way to run replaceRE before the markdown is rendered to HTML?