Skip to content
Put shoppable video on your store todayInstall on Shopify
Tutorial

Use a Video Instead of an Image on Shopify Product Cards

Shopify product cards show a still frame even when the first media item is a video. Here is how to make the card play the video instead, on Dawn and Horizon, without turning your collection page into a slideshow that never loads.

AK
Aashish Kaushik · 11 min read · updated 10 September 2026
Close-up view of a DSLR camera screen capturing a person in a studio setting, focusing on technology and photography.
On this page

Key takeaways

  • By default Dawn and Horizon render a product card with the featured media's preview image, so a video in position one appears as a still.
  • A short edit to card-product.liquid makes the card render a muted, looping, inline video when the featured media is a video.
  • Play only the cards on screen, use preload none and a poster, and cap how many cards carry video, or the collection page will get slow.
  • If the goal is video that sells rather than cards that move, a shoppable widget on the collection page is less code and easier to measure.

Put a video in position one on a product and the product page gallery will show it. The collection card will not. Dawn, Horizon and nearly every Online Store 2.0 theme render the card with the featured media's preview image, so what the shopper sees is the video's first frame as a still.

That is a sensible default, because a grid of twenty autoplaying videos is a slow page. But there are cases where a moving card is worth it: a small catalogue, products whose motion is the point, a collection page that works as a lookbook. This guide shows how to make the card play the video on Dawn, how to do it without wrecking the page, and when a widget is the better answer.

Before you decide, the product page optimisation guide has the placement evidence for where video actually moves conversion; cards are not always the place.

Decide the behaviour first

There are three ways a video card can behave, and the choice shapes the code.

Autoplay loop, muted, in view. The card plays silently while on screen and pauses when it scrolls off. Best for mobile, where there is no hover. This needs the most guardrails.

Play on hover. The card shows the photo; the video plays when the pointer is over it. Desktop only, no cost for phones. Dawn's existing "second image on hover" setting is a natural base for this.

Poster with a play badge, tap to play. The card stays a still with a small play icon, and a tap opens the video in place or in a modal. Lightest option. Often the honest one, since it is what the shopper expects from a card.

If you are unsure, start with hover on desktop and poster-with-badge on mobile. Escalate to autoplay only for the collections where the motion sells.

The Dawn edit, step by step

Step 1: put the video where the card can find it

Dawn's card reads card_product.featured_media, which is the first item in the product's media grid. For autoplay cards, drag the video to position one in the admin. For hover cards, leave the photo first and put the video at position two, because Dawn's hover setting uses the second media item.

Choose the first frame of the video carefully. It becomes the poster, and on any phone with Low Power Mode, or any browser that blocks autoplay, the poster is what the shopper sees. It should look like a product photo, not a blur.

Keep the clip short and small: 5 to 10 seconds, 720p, square or the same aspect ratio as your card images so the grid stays aligned. A vertical 9:16 clip in a square card gets cropped or letterboxed depending on the theme's CSS.

Step 2: edit card-product.liquid in Dawn

Duplicate the live theme first, and make the edit on the copy. In the code editor, open snippets/card-product.liquid. Find the block that renders the featured media: it starts with a check on card_product.featured_media and contains an <img> with a srcset.

Add a branch above the image so that a video featured media renders a video element instead. Dawn versions differ in exact markup, but the shape is this:

```liquid

{%- if card_product.featured_media -%}

<div class="card__media">

<div class="media media--transparent media--hover-effect">

{%- if card_product.featured_media.media_type == 'video' -%}

<video

class="motion-reduce"

data-card-video

muted

loop

playsinline

preload="none"

poster="{{ card_product.featured_media.preview_image | image_url: width: 533 }}"

aria-label="{{ card_product.featured_media.alt | default: card_product.title | escape }}"

>

{%- for source in card_product.featured_media.sources -%}

{%- if source.format == 'mp4' -%}

<source src="{{ source.url }}" type="{{ source.mime_type }}">

{%- endif -%}

{%- endfor -%}

</video>

{%- else -%}

{%- comment -%} existing <img ... srcset ... > stays here unchanged {%- endcomment -%}

{%- endif -%}

</div>

</div>

{%- endif -%}

```

Notes on the choices:

  • muted, loop and playsinline are the attributes phones require for silent inline playback. Without all three, iOS shows a play button.
  • There is deliberately no autoplay attribute. Playback is started by the script in the next step, only when the card is in view. An autoplay attribute on twenty cards would try to start all of them.
  • preload="none" stops the browser fetching any video bytes until asked. The poster carries the visual until then.
  • Only MP4 sources are listed. Shopify also provides an HLS stream, which Chrome cannot play; listing MP4 alone keeps behaviour consistent across browsers.
  • The motion-reduce class is Dawn's hook for respecting the operating system's reduced-motion setting.

The CSS for .card__media video should match whatever .card__media img does: width:100%; height:100%; object-fit:cover; display:block. Add it in assets/component-card.css or the theme's custom CSS.

Step 3: play only what is on screen

This is the part that separates a usable collection page from a slow one. A small script watches the video cards and plays a card when it enters the viewport, pausing it when it leaves. Add it as a deferred script in layout/theme.liquid or as a new asset:

```js

document.addEventListener('DOMContentLoaded', () => {

const videos = document.querySelectorAll('video[data-card-video]');

if (!videos.length || !('IntersectionObserver' in window)) return;

if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;

const io = new IntersectionObserver((entries) => {

entries.forEach(({ target, isIntersecting }) => {

if (isIntersecting) {

target.muted = true;

const p = target.play();

if (p) p.catch(() => {});

} else {

target.pause();

}

});

}, { threshold: 0.5 });

videos.forEach((v) => io.observe(v));

});

```

Three things it does on purpose. It bails out entirely if the shopper has reduced motion enabled. It sets muted as a property before calling play(), because some browsers ignore the attribute for autoplay eligibility when the element was created by a template. And it swallows the rejection from play(), which is what happens in iOS Low Power Mode, so that the poster simply stays.

With threshold: 0.5, a card starts when half of it is visible, so on a two-column mobile grid at most four to six cards play at once.

Cap it

Even with in-view playback, a collection of 48 products with a video on every card is a lot of decoding on a mid-range phone. Either restrict video to the first row or two (check forloop.index in the collection grid and pass a flag into the card snippet) or reserve video cards for a curated collection rather than the full catalogue.

Step 4: check what else reads the first media item

Moving a video into position one affects more than the card. Several other systems read the product's featured media and expect an image.

  • Social previews. Shopify's default og:image uses the product's featured image. For a video in position one, that resolves to the video's preview frame, which is why the first frame has to look like a photo.
  • Shopping feeds. Google Merchant Center, Meta catalogue and marketplace feed apps usually take the first product image for image_link. Some read product.featured_image, which returns the poster; others read product.images, which skips the video and returns the first real image. Check the feed after the change and make sure the listing still has a proper photo.
  • Email and cart. Abandoned-cart emails and the cart drawer use the variant image or the featured image. Both fall back sensibly, but confirm the poster looks right at thumbnail size.

If any of these break, the hover approach (photo first, video second) sidesteps all of them and is often the better trade.

The hover variant for desktop

Dawn's collection settings include an option to show the second media item on hover. The stock implementation swaps in a second <img>. Adapting it for video keeps the still photo as the default and plays the clip only for desktop shoppers who hover.

In the same snippet, where the secondary image is rendered (the block that checks card_product.media[1] and the show_secondary_image flag), add a video branch:

```liquid

{%- if show_secondary_image and card_product.media[1] != null -%}

{%- if card_product.media[1].media_type == 'video' -%}

<video class="motion-reduce" data-card-hover muted loop playsinline preload="none"

poster="{{ card_product.media[1].preview_image | image_url: width: 533 }}">

{%- for source in card_product.media[1].sources -%}

{%- if source.format == 'mp4' -%}

<source src="{{ source.url }}" type="{{ source.mime_type }}">

{%- endif -%}

{%- endfor -%}

</video>

{%- else -%}

{%- comment -%} existing secondary <img> {%- endcomment -%}

{%- endif -%}

{%- endif -%}

```

Then a few lines of script play on mouseenter and pause on mouseleave:

```js

document.querySelectorAll('.card__media').forEach((media) => {

const v = media.querySelector('video[data-card-hover]');

if (!v) return;

media.addEventListener('mouseenter', () => { v.muted = true; v.play().catch(() => {}); });

media.addEventListener('mouseleave', () => { v.pause(); v.currentTime = 0; });

});

```

Dawn's existing hover CSS fades the second media in over the first; the video inherits that if it uses the same classes as the secondary image. Phones have no hover, so mobile shoppers get the photo, which is often the right outcome.

Cards that appear after page load

card-product.liquid is reused by more than the collection grid. Dawn renders the same snippet in predictive search results, the "you may also like" recommendations section, and sometimes in cart drawer upsells. Two consequences follow.

First, the observer script above runs once on DOMContentLoaded, so cards injected later by search or recommendations are never observed and never play. If you want them to, wrap the observer setup in a function and call it again after those sections load, or use a MutationObserver on the document body to pick up new video[data-card-video] elements. Keep it simple: for most stores, video cards in the collection grid are enough, and cards in search and recommendations can stay as images.

Second, if you would rather video cards appear only in the main grid, pass a flag into the snippet. Dawn's main-collection-product-grid.liquid renders each card with a render 'card-product' call; add a parameter such as allow_video: true there, default it to false inside the snippet, and check it in the branch. Search and recommendations then render the stock image card without any further change.

Aspect ratio and cropping

Dawn's card media container uses the product image's aspect ratio, or a fixed ratio set in the theme editor (square, portrait, or adapt to image). A video that does not match will be letterboxed or cropped depending on object-fit.

Export card videos at the same ratio as your product photos. If your photos are square, a 1:1 crop of the clip keeps the grid even. If the theme is set to portrait cards, 4:5 works and 9:16 will lose the top and bottom. Setting object-fit: cover on the video element crops rather than letterboxes, which usually looks better, but make sure the product stays inside the safe area of the frame when you export.

Check the grid on both a phone (two columns) and a wide desktop (four or five columns). A clip that fills a two-column card can look small and busy at four columns, where a still photo would have been clearer.

Horizon and other themes

Horizon's product card is also a snippet, but the file names and structure differ from Dawn's and change between versions. The approach is identical: find where the card renders the featured media's image, branch on media_type == 'video', output a muted inline video with preload="none" and a poster, and drive playback from an in-view observer. Search the theme's snippets for featured_media to find the right file.

Arippula product page with a shoppable video rail beside the product gallery

Themes that loop over product.images rather than product.media cannot see video at all, on cards or anywhere else. That is a bigger fix and the product video not showing guide covers it.

Video product card approaches compared

ApproachMobileDesktopPage costEffort
Autoplay in viewPlays silentlyPlays silentlyMedium, needs cap and observerSnippet edit plus script
Hover to playShows photoPlays on hoverLowSnippet edit plus small script
Poster with play badgeTap to playClick to playLowestSnippet edit and CSS
Shoppable widget on the collection pageLazy-loads, tags productsSameLowApp block, no code

Measuring the cost

Before publishing the duplicate theme, run a mobile Lighthouse test on a collection page in both themes. Watch three numbers: Largest Contentful Paint (the poster of a video card in the first row is now a candidate), Total Blocking Time (the observer script should add almost nothing), and total transferred bytes before any scroll (should be posters only, no MP4 requests).

Open the page on a real phone with the Network tab attached. If you see MP4 downloads before scrolling, preload is wrong or the observer is playing off-screen cards. If the page is noticeably slower than the image-only version, reduce the number of video cards rather than the video quality; it is the count that hurts.

The video and bounce rate article has the full before-and-after method for pages with video.

Video product cards launch checklist

  • Edit made on a duplicate theme and previewed, not on the live theme
  • Video is position one (autoplay) or position two (hover) in the product's media grid
  • First frame chosen so the poster reads as a product photo
  • Clip 5 to 10 seconds, 720p, matching the card aspect ratio
  • Video element has muted, loop, playsinline and preload none; no autoplay attribute
  • Only MP4 sources listed
  • In-view observer plays and pauses; reduced motion respected
  • Number of video cards per page capped
  • Mobile Lighthouse compared before and after
  • Tested on a real iPhone and Android phone, including with Low Power Mode on

When cards are the wrong place for video

Ask what the video is for. If the answer is "the collection page should feel alive", moving cards do that. If the answer is "the video should sell the product", a card is a weak container: it is small, it has no product tag, no add-to-cart, and no attribution.

A shoppable widget placed on the collection template solves that with an app block and no snippet edits. A carousel or grid above the product rows plays reels and UGC lazily, tags each clip to a product, and reports views, watch time, add-to-cart and revenue per video. The cards stay as images, which keeps the page light, and the video does the persuading in a container built for it.

The shoppable video examples collection shows both patterns on real collection pages, and the short-form video and ecommerce sales article covers what the tagged approach changes in the numbers.

Do the card edit when the catalogue is small and the motion is the product. Do the widget when you want to know whether the video paid for itself.

Frequently asked questions

Can a Shopify product card show a video instead of an image?
Yes, with a theme edit. Dawn and most Online Store 2.0 themes render the featured media's preview image on cards.
Which file do I edit in Dawn to put video on product cards?
snippets/card-product.liquid. It is used by collection grids, search results, featured collections and recommendations, so the change applies everywhere cards appear. Make it on a duplicate theme first and preview before publishing.
Will video product cards slow down my collection page?
They will if every card downloads its video on page load. Use preload none, a poster image, an IntersectionObserver that plays only cards in view, and cap the number of video cards per page.
Do video product cards autoplay on iPhone?
Only if the video element has muted, autoplay, loop and playsinline. Without muted and playsinline, iOS shows the first frame with a play button.
Can I make the video play on hover instead of autoplay?
Yes, and on desktop it is the better pattern. Dawn already has a setting to show the second media item on hover.
Is there a way to get video on collection pages without editing the theme?
Yes. Place a shoppable video widget on the collection template as an app block, above or between the product rows.

On the Shopify App Store

Put shoppable video on your store today

Stories, carousels and reels on any Shopify theme. Free plan, no code.

Install on Shopify

Or reach us directly

About the author

Aashish Kaushik

Founder

Builds Shopify apps and SaaS products at ByteInfy.

More from Aashish

Get new articles by email

No more than one a week. Unsubscribe in one click.

Keep reading

A smartphone with the Instagram logo on display, placed on a wooden surface. Perfect for technology and social media the

How to Embed a Single Instagram Reel on Shopify (no-app vs app)

You can embed one public Instagram Reel on a Shopify page in five minutes with Instagram's own embed code and no app. It works, with three limits worth knowing about before you do it on a product page. This guide covers the no-app route step by step, what it cannot do, and when a widget is the better choice.

22 September 2026 · 8 min readRead
Close-up of a classic reel-to-reel tape recorder on a wooden surface, showcasing audio nostalgia.

How to Tag Multiple Products in One Reel on Your Shopify Store

A reel that shows an outfit, a routine or a bundle sells more than one product, and a single tag wastes the other items on screen. Here is when multi-tagging is worth it, how to set it up on a Shopify store, how to order the tags, and how to see which tag actually sells.

16 September 2026 · 9 min readRead
Man playing guitar while recording a vlog video using a smartphone.

Shopify Video Not Playing on iPhone/Safari: Codec and Autoplay Fixes

A video that plays in Chrome on your laptop and shows a blank frame on an iPhone is almost always one of six things: the wrong codec, a missing autoplay attribute, an iPhone setting, a hosting problem with range requests, a script calling play at the wrong time, or a lazy-load quirk. Here is each one, how to tell which you have, and the fix.

15 September 2026 · 11 min readRead
WhatsApp