If you want your Shopify storefront to feel faster and more polished, view transitions are one of the simplest wins right now.
The best part: for basic transitions, you do not need custom JavaScript routing. In a Liquid theme, you can often get a great result by enabling automatic transitions and adding view-transition-name to matching elements like product images and titles.
In this guide, we’ll keep it practical and minimal.
Why this works well in Shopify
Shopify themes are multi-page by default. Users move between collection pages, product pages, and content pages through normal links.
With view transitions enabled, the browser animates that page change instead of doing a hard visual cut. If two elements share the same view-transition-name on the old and new pages, the browser can animate them as a shared element transition.
That means your product card image on a collection page can smoothly transition into the product hero image on the product page.
Step 1: Enable automatic view transitions
Add this in your <head> (usually in theme.liquid):
<style>
@view-transition {
navigation: auto;
}
@media (prefers-reduced-motion: reduce) {
::view-transition-old(root),
::view-transition-new(root) {
animation-duration: 0s;
}
}
</style>Code language: HTML, XML (xml)
That’s enough to get a clean default fade between pages in supporting browsers.
Step 2: Add view-transition-name to product cards
In your product grid/snippet (for example card-product.liquid), add inline style names to image and title.
<a href="{{ product.url }}" class="card-product-link">
{{
product.featured_image
| image_url: width: 900
| image_tag:
loading: 'lazy',
alt: product.title,
style: 'view-transition-name: product-image-' | append: product.id
}}
<h3 style="view-transition-name: product-title-{{ product.id }};">
{{ product.title }}
</h3>
</a>Code language: Django (django)
Step 3: Use the same names on the product page
On product.json sections (commonly in main-product.liquid), use matching names:
{%- assign selected = product.selected_or_first_available_variant -%}
{{
product.featured_image
| image_url: width: 1600
| image_tag:
loading: 'eager',
fetchpriority: 'high',
alt: product.title,
style: 'view-transition-name: product-image-' | append: product.id
}}
<h1 style="view-transition-name: product-title-{{ product.id }};">
{{ product.title }}
</h1>Code language: Django (django)
Now the browser has matching elements to animate between pages.
Practical rules to avoid bugs
- Keep each view-transition-name unique per page.
- Match names exactly between origin and destination pages.
- Start with images and headings only.
- Let unsupported browsers fall back naturally.
- Respect reduced motion preferences.
QA checklist before launch
- Test collection → product → back navigation.
- Test product links from search and featured sections.
- Confirm no duplicate view-transition-name values on the same page.
- Check reduced-motion behavior.
- Validate on mobile and desktop.
Conclusion
If you’ve been putting off page transitions because they felt “too JS-heavy,” this is your shortcut. In many Shopify themes, @view-transition { navigation: auto; } plus a few view-transition-name attributes gets you 80% of the value with minimal implementation risk.
Leave a Comment