Last updated

Media Tag

The media_tag filter turns an image or video into a complete, responsive HTML element. Instead of hand-writing an <img> with a srcset, sizes, and loading, or a <video> with a poster and playback flags, you pipe the media through media_tag and get correct markup with sensible defaults.

{{ section.settings.image | media_tag }}
<img
  src="https://cdn.example.com/tr:w-1600,f-auto,q-80/banner.jpg"
  srcset="https://cdn.example.com/tr:w-400,f-auto,q-80/banner.jpg 400w,
          https://cdn.example.com/tr:w-800,f-auto,q-80/banner.jpg 800w,
          https://cdn.example.com/tr:w-1200,f-auto,q-80/banner.jpg 1200w,
          https://cdn.example.com/tr:w-1600,f-auto,q-80/banner.jpg 1600w"
  sizes="100vw"
  alt=""
  loading="lazy"
  decoding="async">

It builds on the same ImageKit pipeline as image_url — every transformation that filter understands is available here too.

Input

media_tag accepts the same inputs as image_url: an image or video object (such as section.settings.image, section.settings.bg_video, or product.image), a hash with a url/src key, or a plain URL string. Image-picker and video-picker settings both resolve to plain URL strings.

The filter decides whether to render an <img> or a <video> from the media itself:

  • A media object whose type is video, or a URL whose path ends in .mp4, .mov, .webm, or .m4v<video>.
  • Anything else → <img>.

Images

Options

Every option is optional. Any option not listed below is emitted verbatim as an HTML attribute (class, style, id, data-*, fetchpriority, …), so you can attach whatever the markup needs.

OptionDefaultEffect
sizes100vw (or {width}px if width set)The sizes attribute — tell the browser the rendered size.
widths400,800,1200,1600Comma-separated widths used to build the srcset ladder.
widthA fixed display width: builds a [width, width×2] retina srcset, sets the width attribute, and defaults sizes to {width}px.
heightThe height attribute (for layout stability).
quality80Image quality, 1–100 (q-).
formatautoOutput format (f-); auto lets ImageKit negotiate WebP/AVIF.
cropFocus point: top, bottom, left, right, center (fo-).
transformA raw ImageKit transform string applied to every variant (see below).
loadinglazyThe loading attribute — set eager for above-the-fold images.
altthe image's alt text, else ""The alt attribute.

decoding="async" is always emitted.

Fluid width (default)

With no width, media_tag emits a width-based srcset from the widths ladder and lets sizes tell the browser which to pick. Set sizes to match your layout:

{{ product.image | media_tag: sizes: '(max-width: 768px) 100vw, 600px', alt: product.title }}

Fixed width

Pass a width when the image renders at a known size. The ladder collapses to that width plus its 2× retina variant, and sizes defaults to {width}px:

{{ section.settings.logo | media_tag: width: 240, alt: 'Logo' }}
<img
  src="https://cdn.example.com/tr:w-480,f-auto,q-80/logo.png"
  srcset="https://cdn.example.com/tr:w-240,f-auto,q-80/logo.png 240w,
          https://cdn.example.com/tr:w-480,f-auto,q-80/logo.png 480w"
  sizes="240px" width="240" alt="Logo" loading="lazy" decoding="async">

Custom widths and transforms

{{ product.image | media_tag: widths: '300,600,900', quality: 90, crop: 'center', class: 'product__img' }}

width, height, quality, format, and crop map to ImageKit exactly as they do for image_url. Anything outside those named parameters — crop modes, effects, named presets — goes through transform:

{{ product.image | media_tag: transform: 'c-at_max,e-grayscale' }}

Don't put a w- token in transform — width is owned by the filter (it drives the srcset). Use width/widths instead.

Videos

A video URL renders a <video>. The source is transcoded to MP4 for broad compatibility and a poster frame is generated automatically from the video's first frame.

{{ section.settings.bg_video | media_tag: autoplay: true, loop: true, muted: true }}
<video
  src="https://cdn.example.com/clip.mp4?tr=f-mp4"
  poster="https://cdn.example.com/clip.mp4/ik-thumbnail.jpg"
  autoplay loop muted playsinline></video>

Options

OptionDefaultEffect
autoplayoffAdds the autoplay flag.
loopoffAdds the loop flag.
mutedoffAdds the muted flag.
controlsoffShows the native player controls.
posterauto (ImageKit thumbnail)A poster image URL; pass your own to override the generated thumbnail.
formatmp4ImageKit video format.
qualityImageKit video quality.
transformA raw ImageKit video transform string.

playsinline is added automatically whenever muted or autoplay is set, so autoplaying background videos work on mobile. As with images, any other option (such as class) is emitted as an HTML attribute.

{{ section.settings.promo | media_tag: controls: true, poster: section.settings.promo_poster, class: 'promo__video' }}

Behavior

  • Only ImageKit media is transformed. If the URL points to a third-party host, media_tag emits a plain <img>/<video> with the original src and no transform, srcset, or generated poster.
  • Image objects fill in width, height, and alt. When the input carries them (for example product.image), media_tag adds width/height for layout stability and uses the image's alt text. The srcset ladder is also capped to the source's intrinsic width, so the filter never requests an upscaled rendition.
  • Picker settings are plain strings. Image- and video-picker settings have no width/height/alt, so pass width/height/alt yourself if you need them.
  • Output is escaped. All attribute values are HTML-escaped, and event-handler attribute names (onerror, onload, and the like) are dropped — a media_tag can never inject script.
  • Blank input renders nothing. If the media is empty, media_tag returns an empty string.

Examples

Above-the-fold hero image (skip lazy loading, hint high priority):

{{ section.settings.hero | media_tag: loading: 'eager', fetchpriority: 'high', sizes: '100vw', class: 'hero__img' }}

Product card thumbnail at a fixed size:

{{ product.image | media_tag: width: 400, alt: product.title, class: 'card__img' }}

Autoplaying background video:

{{ section.settings.bg_video | media_tag: autoplay: true, loop: true, muted: true, class: 'section__bg' }}

See also