Srcset in liquid loop

How do I tell the browser about the srcset images I have when they are pulled from a .yml file loop?
where do I put the srcset tag? … I don’t understand :slight_smile: thank you for any pointers.

Let’s start with what a no Jekyll srcset approach looks like.

  url size,
  url size,
  url size
 src="default url"


  /wp-content/uploads/flamingo4x.jpg 4025w,
  /wp-content/uploads/flamingo3x.jpg 3019w,
  /wp-content/uploads/flamingo2x.jpg 2013w,
  /wp-content/uploads/flamingo1x.jpg 1006w
1 Like

You already know how to do this.

src="{{item.image | relative_url }}" 

So do the same for srcset.

Hint: for a given image of multiple sizes, the for loop goes inside the img tag, not outside it.

You’ll still keep your outer for loop to iterate over completely different images.

1 Like

yes, I don’t understand that - I don’t know how to write the html srcset into the yaml file. the image url is in that yaml file … I don’t get it :slight_smile:

Okay thanks. I thought your question was on just the loop, not how to write YAML.

Well what you want is an array of images. Where each image has multiple fields. ie a hash.
One field as a string for URL and one field as another array for srcset.

I am going to assume relative URLs here on the same domain.

  - full: "assets/dog.jpeg" # src
    resized:            # srcset
      - "assets/dog300.jpeg 300w"
      - "assets/dog800.jpeg 800w"

  - full: "assets/cat.jpeg" # src
    resized:            # srcset
      - "assets/cat300.jpeg 300w"
      - "assets/cat800.jpeg 800w"

I would highly recommend not writing such low level code yourself.

It is hard to maintain. It does not scale well and is error prone. If you want to add 10 images you have to add 10 blocks of say 5 lines each to your YAML file and they must match up exactly with the images in your assets including the resized ones.
Also please don’t resize manually. It will get forgotten or a mistake will happen eventually.

Rather use automation.

The Jekyll picture tag plugin will resize images for you at build time, given the full size image.

Plus it will build the srcset value for you :slight_smile:

Example from that page:

  1. Install
  2. Write this: {% picture test.jpg %}
  3. Get this:
<!-- Formatted for readability -->

<img src="/generated/test-800-195f7d.jpg"
    /generated/test-400-195f7d.jpg   400w,
    /generated/test-600-195f7d.jpg   600w,
    /generated/test-800-195f7d.jpg   800w,
    /generated/test-1000-195f7d.jpg 1000w
1 Like

If you need to provide say 3 resized images to handle small mobile, big mobile and tablet, then use srcset and gem above.

If you only need to take a full size image and make a web friendly version (like not wider than 1000px) and/or want to make a thumbnail of 200px, then I have a plugin you can use it. It is has fewer features but it much simpler to use and how it is made. It’s a Ruby script of 41 lines.

I link to a demo where I used it for a image gallery hosted on Netlify

1 Like

Absolutely, I’ll just write them into one html page and forget about the yaml file loop. Since its 30 items and only 1 or 2 added per year that will do and jekyll produced the html so I can use that for the gallery page and just add the srcset. The plugin looks good. I do the same - I have a bash script that calls imagemagick and cwebp creating a full set of responsive images from all images in a folder. Generating the srcset entries should be easy too once I have settled on the breakpoint widths.
I am starting to think there is a balance to how much liquid is reasonable :slight_smile:

Thank you for all the input - I am learning.

1 Like

Okay good to hear.

If you programmatically always generate say 300px and 800px and 1000px images, you can avoid hard coding that as YAML.

Given image name “dog.jpeg”
And split by dot into “dog” and “.jpeg”
And config file with

  - "300"
  - "800"
  - "1000"

Your img tag can use liquid to generate srcset like this.

<img src="{{ title }}.jpeg"
    {% for size in site.sizes %}
    /assets/img/resized/{{ title }}_{{ size }}.jpeg {{ size }}W,
    {% endfor %}

You’ll need to use unless or if so you only insert the , where the for loop index is not the last. There’s an index variable built into for loops like forloop.index or similar.

Or you can iterate over your YAML images list. Then your YAML only needs to be:

- "dog.jpeg"
- "cat.jpeg"

Or even just “dog” to avoid having to use split.

You can use link Liquid tag against src value so Jekyll will validate that the path exists on disk. To avoid YAML and actual files going out of sync

You can avoid even putting your images in YAML at all, like this.

You could have an assets directory where you standard images are. These can be in version control.


And your unversioned resized images in


Then with Jekyll you can iterate over all images in the “full” directory, No YAML data to lookup.

Something like this. To filter assets to images only and then to get the name or filename of each. Not sure I got the syntax right for each bit but this pattern will serve you

{% assign full_image_names = site.static_files 
     | where_expr: "item", "item.dir == "assets/img/full" 
     | map: "name" 

Maybe you filter by "item.ext" == "jpeg" instead. Check the Jekyll docs. Static files have different attributes such as extension which site.pages items don’t have

1 Like

How can I give the html srcset image link in a markdown blog post? … is there a way?

HTML is valid in markdown files. Just don’t add empty lines and you’ll be fine.


## My heading

<img src="{{ page.image }} />

## Another heading

<div align="center">
    <img src="{{ page.image }} />

Bad - using empty lines will cause indented lines to become code block.

<div align="center">

    <img src="{{ page.image }} />


You can even wrap markdown in HTML if you don’t indent.

<div align="center">

### Heading

- Markdown bullet
- another bullet <button>Text</button

1 Like

Thank you! that is what happened - I have a yasnippet expanding and that html has indentation and it made the whole thing a codeblock … :slight_smile:

If your snippet is large or you want to add empty lines for readability for yourself, then put the HTML in an includes file.

Then call it


## My heading

<img src="{{ page.image }} />

## Another heading

{% includes image.html src=page.image %}

that is good to know, but with the srcset it would get out of hand - it would have to have a for loop in the include image html to provide the correct images for that particular blogpost and the alternate text for each pulling that from somewhere … - plus I would not see the names of the images when editing an old post.

You could pass multiple parameters to the includes.

    title: My title
    my_src: picture.jpeg
      - picture-100.jpeg
      - picture-800.jpeg

{% include image.html src=page.image.my_src srcset=page.image.src_set title=page.image.title %}

With the for loop inside the includes.

Or even pass an object.

{% include image.html image_fields=page.image %}

And of course you can reference for YAML file instead of page data.

I think that is too complicated for me - every post has one ‘feature’ image if you will - then some posts have 1 or 2 or 3 or more images - some have none. To wrap all those use cases into yaml, json or liquid logic seems overkill compared to just placing the snippets and doing a regex replace with the image name for each snippet expansion.

Have a look at this response if you’re able to install plugins:

Two plugins allow you to write images via Markdown e.g. ![my image](my-image.jpg) and generate srcset markup and all the resized images. No YAML, no Liquid loops, no includes, etc.

1 Like

Thanks for the recommendation. I suggested that plugin too and OP said it looks good but he decided not to go with it.

Maybe because he wants to rely on his existing pipeline of processing images, at the cost of having to write more Liquid himself.