{"title":"image_tag - Liquid Filter Reference","slug":"image-tag-filter-reference","url":"https://support.storeconnect.com/articles/image-tag-filter-reference","url_markdown":"https://support.storeconnect.com/articles/image-tag-filter-reference.md","subtitle":null,"summary":"Output a complete, responsive `\u0026lt;img\u0026gt;` element for a StoreConnect image, with a sized Cloudinary URL, an automatic srcset, alt text and loading hints. Use it in theme templates instead of writing image markup by hand.","type":"Developer_Documentation","video_url":"","keywords":"liquid, filters, image_tag, img, srcset, sizes, responsive images, cloudinary, lazy loading, alt text, fetchpriority, theme, storeconnect","last_modified":"2026-11-04T01:42:14+0000","body_markdown":"## Description\n\nThe `image_tag` filter turns an image into a complete `\u003cimg\u003e` element in one call. Given an [Image](image-liquid-object-reference) object, it builds a Cloudinary URL at the size you ask for, adds a responsive `srcset`, fills in the alt text from the media record, and sets `width`, `height`, `loading` and `decoding` so the browser can reserve space and load the image efficiently.\n\n| Property | Value |\n|----------|-------|\n| **Return Type** | string (HTML) |\n| **Category** | images |\n| **Available in** | Storefront templates. Not available in POS templates. |\n\n\n```liquid\n\n{{ product.image | image_tag: width: 800, sizes: \"(max-width: 640px) 100vw, 50vw\" }}\n```\n\n\nThe filter accepts two kinds of input:\n\n- **An Image object**, such as `product.image` or `article.hero_image`. The filter reads the media record to build the URL, fill in the alt text and dimensions, and generate a `srcset`.\n- **A URL string**, usually the output of [`image_url`](image-url-filter-reference). Without the media record, the filter emits only the attributes you pass, plus the default `loading` and `decoding` values. No alt text, dimensions or `srcset` are derived.\n\nAny other input returns an empty string.\n\n## Options\n\nThe `width`, `height`, `crop` and `quality` options work exactly as they do for [`image_url`](image-url-filter-reference): the image is never enlarged past the original, no dimension exceeds 5120 pixels, and a missing dimension is calculated from the aspect ratio.\n\n| Option | Default | Description |\n|--------|---------|-------------|\n| `width` | Original width | Width in pixels. |\n| `height` | Calculated from the aspect ratio | Height in pixels. |\n| `crop` | `fit` | Cloudinary crop mode: `fit`, `fill`, `scale`, `pad`, `crop`, `thumb` or `limit`. |\n| `quality` | `auto` | `auto`, `best`, `good`, `eco`, `low`, `none`, or a number from `1` to `100`. |\n| `alt` | The image's **Alt Text** | Alt text. With a URL string input, the default is empty. |\n| `class` | None | CSS classes. |\n| `id` | None | HTML `id`. |\n| `loading` | `lazy` | `lazy` or `eager`. |\n| `decoding` | `async` | `async`, `sync` or `auto`. |\n| `fetchpriority` | None | `high`, `low` or `auto`. |\n| `sizes` | None | The `sizes` attribute. Emitted only when the tag has a `srcset`. |\n| `widths` | The default width ladder | Comma-separated widths to build the `srcset` from, such as `\"400,800,1200\"`. `srcset_widths` is accepted as an alias. |\n| `srcset` | Generated | An explicit `srcset` string, output as written. Pass `srcset: nil` to leave the attribute off. |\n| `data-*`, `aria-*` | None | Passed through to the element, for example `data-zoom: \"true\"` or `aria-label: \"Front view\"`. |\n\nAn unrecognized value for `loading`, `decoding`, `crop` or `fetchpriority` falls back to the default. Attributes other than those listed, including event handlers such as `onclick`, are never output, and every value is HTML-escaped.\n\n## How the srcset is built\n\nFor an Image object, `image_tag` generates a `srcset` automatically when all of these are true:\n\n- The image is hosted on Cloudinary and is not a GIF or SVG.\n- The media record has a stored width and height.\n- The crop is `fit` or `limit` (the aspect ratio is preserved).\n- `quality` is left at the default.\n\nThe candidates come from a fixed ladder of widths: 320, 400, 512, 640, 800, 1024, 1280, 1600 and 2048 pixels. Widths larger than the original image are left out. When you pass `width`, the ladder stops at the first width that reaches twice that value, so a high-density screen can still pick a sharp image without the browser being offered anything larger.\n\nTo control the candidates yourself, pass `widths`. This also works with an exact crop such as `fill`, and with a custom `quality`, where the default ladder is skipped. Each candidate keeps the crop and aspect ratio of the `src`.\n\n:::tip\nAlways pass `sizes` with a responsive image. Without it, the browser assumes the image fills the full viewport width and downloads a larger file than it needs.\n:::\n\n## Width and height attributes\n\nThe `width` and `height` attributes describe the image the browser receives, not the box you asked for. With `fit` or `limit`, a box that does not match the image's shape delivers a smaller image in one direction, and the attributes follow that delivered size. For example, a 1600 by 1200 image requested at `width: 800, height: 800` is delivered at 800 by 600, and the tag carries `width=\"800\" height=\"600\"`. Exact crops such as `fill` fill the box, so the attributes match the request.\n\n## Examples\n\nA product card image that loads lazily and picks a size from the default ladder. The product image here is 1600 by 1200 pixels, with the alt text \"Blue linen shirt\":\n\n\n```liquid\n\n{{ product.image | image_tag: width: 400, sizes: \"(max-width: 640px) 50vw, 25vw\", class: \"product-card__image\" }}\n```\n\n\n**Output** (URLs shortened):\n\n```html\n\n\u003cimg src=\"https://res.cloudinary.com/…/c_fit,h_300,w_400/…\" srcset=\"https://res.cloudinary.com/…/c_limit,w_320/… 320w, https://res.cloudinary.com/…/c_limit,w_400/… 400w, https://res.cloudinary.com/…/c_limit,w_512/… 512w, https://res.cloudinary.com/…/c_limit,w_640/… 640w, https://res.cloudinary.com/…/c_limit,w_800/… 800w\" sizes=\"(max-width: 640px) 50vw, 25vw\" alt=\"Blue linen shirt\" width=\"400\" height=\"300\" class=\"product-card__image\" loading=\"lazy\" decoding=\"async\"\u003e\n```\n\nA hero image above the fold, cropped to an exact box, with explicit candidate widths and a high fetch priority:\n\n\n```liquid\n\n{{ article.hero_image | image_tag: width: 1600, height: 600, crop: \"fill\", widths: \"800,1200,1600\", sizes: \"100vw\", loading: \"eager\", fetchpriority: \"high\", alt: article.title }}\n```\n\n\nAn image with data and ARIA attributes for a gallery script:\n\n\n```liquid\n\n{{ product.image | image_tag: width: 800, data-zoom: \"true\", aria-label: product.name }}\n```\n\n\nChaining from `image_url`, for themes ported from Shopify:\n\n\n```liquid\n\n{{ product.image | image_url: width: 800 | image_tag: alt: product.name, class: \"hero\" }}\n```\n\n\nThis form has no `srcset` or dimensions unless you pass them, so prefer passing the Image object straight to `image_tag`."}