Cloudinary Logo

My site performance improved after I moved my Hugo image content to the cloud. But there was one thing left to do - I still needed to serve dynamic and responsive images for a variety of screen sizes and pixel density.

This post will focus on changes to your site, by serving responsive image from the cloud / content delivery network (CDN) using Cloudinary [referral].

I’ll show you:

  1. How to change to your theme to serve responsive images
  2. How to change to the source of images on the list post layout (using a worked example)
  3. Considerations with responsive Bootstrap themes
  4. What to do if there are any issues

If you haven’t already started using Cloudinary - then read my moving Hugo images to the cloud article first.

Change your theme to serve Cloudinary responsive code

  1. Add Cloudinary to your header

  2. Open your Themes Folder and the file Layouts/Partial/head.html

  3. Copy / Paste in the <head> section, with the other <meta> attributes:

<meta http-equiv="Accept-CH" content="DPR, Viewport-Width, Width">

This is a bit of magic - which means a device’s browser will tell Cloudinary the screen size and pixel density. Client Hints (Accept-CH) allows web browsers to inform servers (or CDN layers) of the required dimensions and pixel densities of each specific image download request.

  1. Add Cloudinary to your footer

  2. Open your Themes Folder - Layouts/Partial/footer.html

  3. Copy / Paste in with the other scripts: <script src="https://cdnjs.cloudflare.com/ajax/libs/cloudinary-core/2.8.2/cloudinary-core-shrinkwrap.min.js"></script>

This adds the Cloudinary javascript to your website - its hosted in the cloud of course, so won’t impact your site performance

  1. Copy / Paste just before the closing </Footer> tag:
1
2
3
4
5
6
{{ "<!-- cloudinary -->" | safeHTML }}
<script type="text/javascript">
    var cl = cloudinary.Cloudinary.new({cloud_name: "demo"}); 
    // replace 'demo' with your cloud name in the line above 
    cl.responsive();
	</script>

Make sure you replace ‘demo’ with your Cloudinary username.

This little bit of script looks for any img with class="cld-responsive" attribute and then passes it to Cloudinary to process the right file for you

Worked Example - Update your image source in your single.post

Most themes will feature an image on the single post (like at the top of this page). If you’ve already moved your images to the cloud and using Cloudinary … you’ve done the hard work.

In my moving Hugo images to the cloud article, we changed the <img html tag,

This is where we left it … mastering the images and serving the best quality, format, etc ..

1
2
3
{{ with .Params.image }}
<img src="{{ $.Site.Params.cloudinary_base_url }}/w_auto,c_scale,f_auto,q_auto,dpr_auto/{{ . }}" alt="post-image"/>
{{ end }}

To make it cloud-responsive (nice term). We make 2 changes:

  • class="cld-responsive" is added
  • image src is changed to data-src

So the final result looks like:

1
2
3
{{ with .Params.image }}
<img class="cld-responsive" data-src="{{ $.Site.Params.cloudinary_base_url }}/w_auto,c_scale,f_auto,q_auto,dpr_auto{{ . }}" alt="post-image"/>
{{ end }}

This must be done for every image - but hopefully there are not too many places (think single and list layout) to make this change. Start by the modifying your most used layouts.

Note: If you are using Bootstrap, or a theme that is responsive, and doesn’t have fixed width div or containers - you’ll probably have to do one more thing (see Test and Go below)

Test and Go …

So now …

  1. Save the file
  2. Commit your changes to Git
  3. Run Hugo server -D and browse to http://Localhost to check every thing is working fine

If you find a problem:

  • Check the source - and the footer section - is the script and the javascript showing
  • Check the config.toml params - did you add the URL in the default [params] section?

Bootstrap / Responsive Theme issue:

If you find your images are breaking out of the <div> and not respecting the size of your columns layout - then you need to set a static width attribute. This is because the bit of responsive javascript calculates the image width based on the nearest element in the DOM with a width.

So I found adding in a style / width attribute fixed the issue and also serves and image at the correct width for the browser

1
2
3
{{ with .Params.image }}
<img style="width:90%" class="cld-responsive" data-src="{{ $.Site.Params.cloudinary_base_url }}/w_auto,c_scale,f_auto,q_auto,dpr_auto{{ . }}" alt="post-image"/>
{{ end }}

Finally - heres an example of the problem - showing the image incorrectly sized for the page width Escaping Ella

This is the cld-responsive image with the size fix:

How did this work for you? Let me know

Linkage