Hugo Theme (Part 6) : Imagekit
Intro
In this post, we will add ImageKit support to our theme. We will use ImageKit to store and deliver our images. We will also use ImageKit to create variants of the images for different resolutions/screen sizes for faster loading and bandwidth saving. You will need an ImageKit account. If you don’t already have one, you can sign up for a free account.
[!Tip]
Use online backup like Google Drive to save your entire Hugo site, use ImageKit to host images and use GitHub with images excluded for version control of other files
ImageKit
ImageKit can resize images to any size on the fly, but we want to restrict it to a few sizes that we want to use. We can use Named Transformations to use simpler names for complex transformations.
In ImageKit dashboard, navigate to Settings > Named transforms and add
Named Transform | Actual Transform String | Status |
---|---|---|
thumb | tr:w-400,c-at_max | Enabled |
mobile | tr:w-640,c-at_max | Enabled |
sm | tr:w-768,c-at_max | Enabled |
md | tr:w-1024,c-at_max | Enabled |
lg | tr:w-1280,c-at_max | Enabled |
xl | tr:w-1536,c-at_max | Enabled |
2xl | tr:w-1920,c-at_max | Enabled |
Now we can use these named transformations with the images hosted at ImageKit to get a specific size. c-at_max
makes sure that we don’t upscale or increase the image dimensions if its smaller than the one requested.
I will also disable dynamic transformations and enable only named transformations. Settings > Images > Restrict unnamed image transformations » ON
[!Tip]
If we want to create the variants on image upload rather than on request, we can also add the transformations to Settings > Media library > Default upload parameters > Post transformations.
Upload an image ImageKit media library so we can test the transformation. Then use the URL with the tr-<transformation_name>
to use variants.
Test named transformations
![Test thumb](https://ik.imagekit.io/psxoierby/tr:n-thumb/pexels-chevanon-photography-1108099.jpg)
![Test md](https://ik.imagekit.io/psxoierby/tr:n-md/pexels-chevanon-photography-1108099.jpg)
Rclone
We will use Rclone to sync our images to ImageKit.
Follow instructions https://rclone.org/downloads/ to install rclone
% sudo -v ; curl https://rclone.org/install.sh | sudo bash
Password:
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 4734 100 4734 0 0 5706 0 --:--:-- --:--:-- --:--:-- 5745
Archive: rclone-current-osx-amd64.zip
creating: tmp_unzip_dir_for_rclone/rclone-v1.65.2-osx-amd64/
inflating: tmp_unzip_dir_for_rclone/rclone-v1.65.2-osx-amd64/git-log.txt [text]
inflating: tmp_unzip_dir_for_rclone/rclone-v1.65.2-osx-amd64/rclone [binary]
inflating: tmp_unzip_dir_for_rclone/rclone-v1.65.2-osx-amd64/rclone.1 [text]
inflating: tmp_unzip_dir_for_rclone/rclone-v1.65.2-osx-amd64/README.html [text]
inflating: tmp_unzip_dir_for_rclone/rclone-v1.65.2-osx-amd64/README.txt [text]
rclone v1.65.2 has successfully installed.
Now run "rclone config" for setup. Check https://rclone.org/docs/ for more details.
Configure rclone with ImageKit media library as remote folder. Start with rclone config
and follow the prompts
% rclone config
e) Edit existing remote
n) New remote
d) Delete remote
r) Rename remote
c) Copy remote
s) Set configuration password
q) Quit config
e/n/d/r/c/s/q> n
Enter name for new remote.
name> imgkit
Option Storage.
Type of storage to configure.
Choose a number from below, or type in your own value.
...
23 / ImageKit.io
\ (imagekit)
...
Storage> 23
Option endpoint.
You can find your ImageKit.io URL endpoint in your [dashboard](https://imagekit.io/dashboard/developer/api-keys)
Enter a value.
endpoint> https://ik.imagekit.io/somepath
Option public_key.
You can find your ImageKit.io public key in your [dashboard](https://imagekit.io/dashboard/developer/api-keys)
Enter a value.
public_key> <public_key>
Option private_key.
You can find your ImageKit.io private key in your [dashboard](https://imagekit.io/dashboard/developer/api-keys)
Enter a value.
private_key> <private_key>
Edit advanced config?
y) Yes
n) No (default)
y/n> n
Configuration complete.
Options:
- type: imagekit
- endpoint: https://ik.imagekit.io/psxoierby
- public_key: <public_key>
- private_key: <private_key>
Keep this "imgkit" remote?
y) Yes this is OK (default)
e) Edit this remote
d) Delete this remote
y/e/d> y
Current remotes:
Name Type
==== ====
imgkit imagekit
e) Edit existing remote
n) New remote
d) Delete remote
r) Rename remote
c) Copy remote
s) Set configuration password
q) Quit config
e/n/d/r/c/s/q> q
Sync the image files to ImageKit media library. Include all the image file extensions to sync. I used only jpg
, jpeg
and png
rclone sync blog/content imgkit: --include "*.{jpg,jpeg,png}"
Run this command after adding new images and they will automatically be available on ImageKit.
Configure Hugo to use ImageKit. In hugo.toml, set imgkit
to true
and imgkitURL
to ImageKit URL endpoint
imagekit = true
imgkitUrl = "https://ik.imagekit.io/somepath"
Hugo Code
layouts/_default/_markup/render-image.html
For external images keep the existing code
{{- $isRemote := strings.HasPrefix .Destination "http" -}}
{{- if or $isRemote (not .Page.Site.Params.imagekit) -}}
<img src="{{ .Destination }}" class="p-0 m-0" {{ if .Page.Site.Params.mediumZoom }} data-zoomable data-zoom-src="{{ .Destination }}"{{ end }} alt="{{ .Text }}" {{ with .Title }} title="{{ . }}"{{ end }} />
For our own images, if imgkit
variable is set in our site settings, we will use ImageKit URLs, otherwise default back to local image URLs
{{- else -}}
{{ $srcMobile := urls.JoinPath .Page.Site.Params.imgkitURL "tr:n-mobile" .Page.RelPermalink .Destination }}
{{ $srcSm := urls.JoinPath .Page.Site.Params.imgkitURL "tr:n-sm" .Page.RelPermalink .Destination }}
{{ $srcMd := urls.JoinPath .Page.Site.Params.imgkitURL "tr:n-md" .Page.RelPermalink .Destination }}
{{ $srcLg := urls.JoinPath .Page.Site.Params.imgkitURL "tr:n-lg" .Page.RelPermalink .Destination }}
{{ $srcXl := urls.JoinPath .Page.Site.Params.imgkitURL "tr:n-xl" .Page.RelPermalink .Destination }}
{{ $src2xl := urls.JoinPath .Page.Site.Params.imgkitURL "tr:n-2xl" .Page.RelPermalink .Destination }}
<img src='{{$srcMobile}}'
srcset='{{ $srcMobile }} 640w, {{ $srcSm }} 768w, {{ $srcMd }} 1024w, {{ $srcLg }} 1280w, {{ $srcXl }} 1536w, {{ $src2xl }} 1920w'
class="p-0 m-0" {{ if .Page.Site.Params.mediumZoom }} data-zoomable data-zoom-src="{{ $src2xl }}"{{ end }} alt="{{ .Text }}" {{ with .Title }} title="{{ . }}"{{ end }} />
{{- end -}}
Do the same thing for our gallery shortcode layouts/shortcodes/gallery.html
{{ $isRemote := strings.HasPrefix $src "http" }}
{{ if or $isRemote (not $page.Site.Params.imagekit) }}
<a href={{$src}} class="glightbox sm:max-w-72" data-gallery={{$gallery}}>
{{ . | $page.RenderString }}
</a>
{{ else }}
{{ $srcThumb := urls.JoinPath $page.Site.Params.imgkitURL "tr:n-thumb" $page.RelPermalink $src }}
{{ $srcMobile := urls.JoinPath $page.Site.Params.imgkitURL "tr:n-mobile" $page.RelPermalink $src }}
{{ $srcSm := urls.JoinPath $page.Site.Params.imgkitURL "tr:n-sm" $page.RelPermalink $src }}
{{ $srcMd := urls.JoinPath $page.Site.Params.imgkitURL "tr:n-md" $page.RelPermalink $src }}
{{ $srcLg := urls.JoinPath $page.Site.Params.imgkitURL "tr:n-lg" $page.RelPermalink $src }}
{{ $srcXl := urls.JoinPath $page.Site.Params.imgkitURL "tr:n-xl" $page.RelPermalink $src }}
{{ $src2xl := urls.JoinPath $page.Site.Params.imgkitURL "tr:n-2xl" $page.RelPermalink $src }}
<a href={{$srcMobile}} class="glightbox sm:max-w-72" data-gallery={{$gallery}}
data-sizes="100%"
data-srcset='{{ $srcMobile }} 640w, {{ $srcSm }} 768w, {{ $srcMd }} 1024w, {{ $srcLg }} 1280w, {{ $srcXl }} 1536w, {{ $src2xl }} 1920w'
>
<img src='{{$srcThumb}}'>
</a>
{{ end }}
We can add similar render blocks for other image hosts if needed in the future.
Thank you for reading. I will post more content shortly. You can also check out other posts in this series below.