How to cache bust static files with a fingerprinted file name?

Here’s an end to end solution. A lot of this was done by @irkode in previous replies, I just abstracted it out into a partial and appended in some of my existing image partial logic.

Keep in mind I just started using Hugo so I don’t really know if this is the best way to do things but:

Previously I had this image.html partial:

{{ $src := print "/images/" .src }}
{{ $height := .height }}
{{ $width := .width }}
{{ $class := .class }}

{{ $img := resources.Get $src | fingerprint }}
<img src="{{ $img.Permalink }}"{{ with $class }} class="{{ $class }}"{{ end }} height="{{ $width | default $img.Height }}" width="{{ $width | default $img.Width }}" alt="{{ index ((split $img "/") | last 1) 0 }}" >

Which was called in an image.html shortcode like this:

{{ $src := .Get "src" }}
{{ $height := .Get "height" }}
{{ $width := .Get "width" }}
{{ $class := .Get "class" }}

{{ partial "image.html" (dict "src" $src "height" $height "width" $width "class" $class) }}

Which can then be used in your content markdown file like this:

{{< image src="hello.jpg" >}}

Here is the new custom image.html partial:

{{ $fingerprintDelimiter := "-" }}
{{ $src := print "/images/" .src }}
{{ $height := .height }}
{{ $width := .width }}
{{ $class := .class }}

{{ with resources.Get $src }}
  <!-- Calculate SHA -->
  {{ $sha256 := sha256 .Content }}
  <!-- Get the file extension -->
  {{ $ext := path.Ext .Name }}
  <!-- Remove extension by removing everything after the last dot -->
  {{ $pathWithoutExt := replaceRE `\.[^.]+$` "" .Name }}
  <!-- Remove leading / -->
  {{ $pathWithoutExt = strings.TrimLeft "/" $pathWithoutExt }}
  <!-- Generate filename -->
  {{ $fullPathWithFingerprint := printf "%s%s%s%s" $pathWithoutExt $fingerprintDelimiter $sha256 $ext }}
  <!-- Copy to destination (virtually) -->
  {{ with resources.Copy $fullPathWithFingerprint . }}
     <!-- Publish to destination by creating the link -->
     <img src="{{ .Permalink }}" {{ with $class }} class="{{ $class }}"{{ end }} height="{{ $width | default .Height }}" width="{{ $width | default .Width }}" alt="{{ index ((split .Name "/") | last 1) 0 }}" >
     <!-- For debugging purposes so you can see the file name, remove this as needed -->
     <p>{{ .Name }} => {{ $fullPathWithFingerprint }}</p>
  {{ end }}
{{ end }}

The shortcode and how you call it didn’t change, but the above solution produces file names with basefile-fingerprint.ext instead of the original basefile.fingerprint.ext.

1 Like