Rendering Images with Hugo

This website is served as static HTML, compiles by a really capable "static-site-generator" called Hugo. I had a problem to solve with rendering images here: sometimes I wanted an image which is local to a particular blog post to also show up in the homepage, which serves the most recent posts. The problem is that the relative URL for the image is different when that content is served on the homepage. I don't want to hard-code absolute URLs, but I do want to use the sources of the webpage in different parts of the website. Therefore, I needed Hugo to somehow intelligently re-write those URLs when compiling the website.

This is where Hugo's relatively new Markdown render hooks come in. I've added the following code to a partial under layouts/_default/_markup/render-image.html

{{ $url := urls.Parse .Destination }}
{{ if or (eq $url.IsAbs true) (hasPrefix .Destination "/") }}
    <img src="{{ .Destination }}" title="{{ .Title }}" alt="{{ .Title }}"/>
{{ else }}
    <img src="{{ .Page.Permalink }}/{{ .Destination }}" title="{{ .Title }}" alt="{{ .Title }}"/>
{{ end }}

This has the effect of prepending the page's absolute URL to the image path at compile time. It is invoked every time a Markdown image element is encountered in the sources. If the image is not local to the page, then the image HTML tag is rendered with the URL unchanged (e.g for external images, or for images served from a folder relative to the webroot, rather than the current page's folder.)

Hugo's render hooks are an interesting and useful addition. As well as images, you can specify render hooks for:

  • image
  • link
  • heading
  • codeblock