/ โ† CLS Debugger Fixes / CLS in Shopify
In this guide
  1. Where Shopify stores usually shift
  2. Testing safely and isolating apps
  3. Product images and galleries
  4. Apps, app blocks and payment buttons
  5. Sections the theme loads later
  6. Theme fonts
  7. The fix, step by step
  8. Keeping the store stable
  9. Questions and answers

Where Shopify stores usually shift

Shopify pages are rendered from Liquid templates on Shopify's servers, so the first HTML is usually complete. The shifts come from what arrives afterwards: images, fonts, app scripts and sections fetched by the theme's JavaScript. Test at least one page of each template type, because they shift for different reasons.

TemplateTypical culprits
Home pageSlideshow or hero images without a fixed ratio, app-injected promotional bars, featured collection cards
CollectionProduct cards with photos of different shapes, review stars and badges added by apps, colour swatches loaded by script
ProductMedia gallery height changing between images, buy-now-pay-later messages, accelerated checkout buttons, reviews and upsell widgets, recommendations below
CartUpsell and shipping-progress widgets, gift wrap options, payment buttons
Every pageTheme fonts, announcement bars from apps, header changes on scroll

Basket drawers and "added to cart" notifications that push content are covered in the cart and notification banner guide, so this guide concentrates on the rest.

Testing safely and isolating apps

Never experiment on the published theme. In the admin, go to Online Store, then Themes, and duplicate the live theme. Preview the copy and share its preview link with anyone helping you. All the changes below can be tested there first.

  1. Run the CLS Debugger on a representative home, collection and product page and note the moved elements and their scores.
  2. Record a throttled load in Chrome DevTools' Performance panel on a phone-sized viewport, with the cache disabled, and scroll the whole page. Product pages often shift further down, where reviews and recommendations load.
  3. Switch off app embeds in the duplicate theme. In the theme editor, open the App embeds panel and turn them off one at a time, re-testing after each. If CLS drops when a particular embed is off, that app is involved.
  4. Look for leftover app code. Older apps, and some that have since been uninstalled, added snippets directly into theme.liquid or product templates. Search the theme code for {% render %} tags and script tags that reference apps you no longer use.

For real-visitor data, use the Core Web Vitals report in Search Console, which groups similar URLs, and the web performance reports in the Shopify admin analytics section, which show how the store performs for real sessions. Both lag behind changes by some weeks.

Product images and galleries

Let the image_tag filter do the work

Current Shopify themes output images with the image_tag filter, which writes width and height attributes from the image's real dimensions automatically. Older themes, and custom sections copied from tutorials, often build the tag by hand with only a src. Replace those with the filter:

{{ product.featured_image
   | image_url: width: 900
   | image_tag:
       loading: 'lazy',
       widths: '360, 540, 720, 900',
       sizes: '(min-width: 990px) 25vw, 50vw',
       alt: product.featured_image.alt }}

If you must write the tag by hand, add width="{{ image.width }}" and height="{{ image.height }}" and let CSS set height: auto. Do not lazy-load the first large image on the page; that helps LCP and does not affect CLS either way once dimensions are present.

Product cards with photos of different shapes

If one product is photographed square and the next is portrait, the cards in a collection grid are different heights and rows can reflow as images load. Many themes have an image ratio setting for product cards, with options such as adapt to image, portrait or square. A fixed ratio makes every card the same height before any image arrives, with images cropped or letterboxed to fit. "Adapt to image" follows each photo's own shape, which is only stable if all your photos share one.

Galleries that change height

On product pages, a gallery that sizes itself to the current image grows or shrinks when the shopper swipes or picks a variant with a differently shaped photo. The change right after a tap is exempt from CLS, but if the new image loads slowly and the gallery resizes more than half a second later, it counts. Give the main media frame a fixed aspect ratio in the theme's CSS and use object-fit: contain so every image fits the same box. Better still, photograph products at one consistent ratio.

๐Ÿ’ก General image sizing, beyond Shopify, is covered in the images guide, and image weight on Shopify in fixing images on Shopify.

Apps, app blocks and payment buttons

Apps add content to a store in three main ways, and each needs a slightly different fix.

Review stars on product cards, buy-now-pay-later messages, trust badges, stock counters, size guide links and "frequently bought together" boxes all appear after the page has painted. Each one pushes the content below it by its own height. Wrap app blocks in a container with a min-height equal to the loaded widget, using the Custom CSS option that many current themes offer in section settings, or your theme's stylesheet:

/* In the product information section's Custom CSS, or assets/base.css */
.product__info-container .shopify-app-block { min-height: 24px; }
.card__information .rating-wrapper { min-height: 20px; }   /* stars on cards */

Class names differ by theme and app; inspect the loaded widget in DevTools to find the right selector and its real height on mobile and desktop.

Accelerated checkout and payment messages

The accelerated checkout buttons output by {{ form | payment_button }} are drawn by a Shopify script after load, and which wallets appear depends on the shopper's device and region. Instalment messaging from {{ form | payment_terms }} also loads asynchronously. Give their containers a minimum height in the theme CSS so the add-to-cart area does not jump. Check the loaded height on an iPhone and an Android phone, as the buttons shown can differ.

โš ๏ธ Uninstalling an app does not always remove code it added to theme files. After removing an app, search the theme for its name and for snippets it created, and remove them on the duplicate theme first.

Sections the theme loads later

Some sections are not in the first HTML. Product recommendations are the classic case: themes such as Dawn render an empty container, wait until it is near the screen, then fetch the finished section from Shopify and insert it. Complementary products, recently viewed items and some predictive search panels work the same way. When the content arrives, anything below it, often the footer or a newsletter block, moves.

Because the section only loads when the shopper scrolls near it, the shift happens mid-scroll, which still counts. Reserve its height:

product-recommendations { display: block; min-height: 420px; }
@media (max-width: 749px) {
  product-recommendations { min-height: 760px; }
}

Measure the loaded section at each breakpoint and use those numbers. If a product sometimes has no recommendations, the theme may remove the section, which leaves a gap closing; hiding the section with a CSS rule when empty is fine as long as that happens before it scrolls into view. Changing the recommendations to render in Liquid rather than through a fetch removes the shift entirely, at the cost of slightly slower first HTML.

Theme fonts

Fonts chosen in Theme settings, under Typography, come from Shopify's font library and are usually written into the page in layout/theme.liquid with the font_face filter:

{{ settings.type_body_font | font_face: font_display: 'swap' }}

With swap, text is drawn in a system font and redrawn when the theme font arrives, which reflows headings and paragraphs if the two fonts differ in size. You have three practical options:

Each extra weight you enable, such as bold body text or a separate heading weight, is another file. Keep the number low. The web fonts guide explains how to tune a fallback font so the swap barely moves anything.

The fix, step by step

Step 1

Test key templates with and without apps

Duplicate the live theme and work only on the copy. Run the CLS Debugger on a home page, a busy collection and a product with several images and variants, and record throttled mobile loads in Chrome DevTools while scrolling. Then turn app embeds off one at a time in the theme editor and retest, noting which apps change the score. Search the theme code for snippets left behind by apps you have removed.

Step 2

Let Liquid output image dimensions

Search the theme's sections and snippets for hand-written <img tags. Replace each with the image_url and image_tag filters, which add width and height automatically, or add width="{{ image.width }}" and height="{{ image.height }}" yourself. Check custom sections, blog templates and any code pasted in by an agency, since built-in theme sections are usually already correct in current themes, and preview the result on a phone.

Step 3

Fix product card and gallery ratios

In the theme editor, set the product card image ratio to a fixed shape such as square or portrait rather than adapting to each image, unless every product photo already shares one shape. On product pages, give the main media frame a fixed aspect ratio in the theme CSS with object-fit: contain, so switching image or variant never changes the gallery's height. Plan future product photography at one consistent ratio.

Step 4

Reserve space for app blocks and payment buttons

For each app that shifts content, inspect its loaded widget on mobile and desktop and note its height. Add a min-height for its container in the section's Custom CSS or the theme stylesheet, including review stars on product cards and instalment messages. Do the same for the accelerated checkout button container and payment terms. Where an app only offers an embed that injects content unpredictably, ask the developer for an app block or a fixed-height option.

Step 5

Reserve space for sections loaded later

Identify sections that the theme fetches after load, such as product recommendations, complementary products and recently viewed items, by scrolling a product page while watching the Network panel. Measure each section once loaded and give its container a matching min-height at each breakpoint in the theme CSS. Decide how products with no recommendations should behave, so the reserved space does not close up while a shopper is reading.

Step 6

Tune the theme fonts

Open layout/theme.liquid and find the font_face filters. Change font_display for the body font to optional, add a preload link built with font_url for the main body face, and switch off font weights and styles you do not really use in Typography settings. If the brand allows, choose a system font for body text. Compare a cold, throttled load before and after to confirm text no longer reflows.

Step 7

Publish and watch field data

When the duplicate theme tests clean in the CLS Debugger on every template, publish it, keeping the old theme unpublished as a fallback. Retest the live pages, since some apps behave differently on the published theme. Then watch the Core Web Vitals report in Search Console and the store's web performance reports over the next four weeks, and recheck after installing any new app or theme update.

Keeping the store stable

Store-wide speed beyond layout shift is covered in Core Web Vitals on Shopify.

Questions and answers

1. Why does my Shopify product page jump when it loads?

The most common causes are apps adding content after the page appears, such as review stars, instalment payment messages and upsell boxes, and the accelerated checkout buttons drawn by Shopify script. Below the product details, recommendation sections that are fetched as you scroll add more movement. A gallery that changes height between images is another. Test the page with app embeds switched off in a duplicate theme to see how much comes from apps.

2. Do Shopify apps cause layout shift?

Many can, because they inject their content with JavaScript after the theme has drawn the page. Whether that shifts the page depends on where the content goes and whether space was reserved for it. App blocks you place in the theme editor are easiest to fix, because you know where they are and can give their container a minimum height. Embeds and older script-based apps may need the developer to offer a fixed-height option.

3. Does the Dawn theme have layout shift problems?

Dawn and other current Shopify themes output images with width and height and generally handle their own sections well, so a fresh install usually has little shift. Problems tend to come from what is added: apps, custom sections, product photos of mixed shapes with the card ratio set to adapt, fonts added in custom code and recommendation sections without reserved height. Testing a clean duplicate theme next to your live one shows how much you have added.

4. Should I change font_display to optional on Shopify?

For body text it is usually the most stable choice. With optional, if the font is not ready almost immediately, the store keeps the system font for that page and uses the theme font on the next page once it is cached, so text never reflows mid-read. For a heading or logo font where the brand look matters more, keep swap and preload that font instead. Edit the font_face filter in theme.liquid on a duplicate theme first.

5. How do I reserve space for product recommendations on Shopify?

Load a product page, scroll to the recommendations and measure the loaded section height on a phone-sized screen and on desktop. Then add a min-height for the recommendations container to the theme CSS, using a media query for the mobile value. The fetched products then fill space that already exists instead of pushing the footer down. If some products have no recommendations, check that the empty space is removed before the shopper reaches it.

6. Will theme updates undo my CLS fixes?

They can. Updating a theme to a new version from the Theme Store replaces the theme files, and edits you made to those files may not carry over. Settings made in the theme editor, such as the card image ratio and section Custom CSS, are usually kept, but code edits in theme.liquid and asset files often need reapplying. Keep a written list of each change, with its file, and retest with the CLS Debugger after every update.

Check your Shopify templates for layout shift

The CLS Debugger records every layout shift while a page loads, names the elements involved, adds up the cumulative score and ranks each shift by impact, so you can see whether theme images, apps or fonts are behind it.

Open CLS Debugger Fixes โ†’
๐Ÿ’ฌ Got a problem?
Related Guides: All CLS Debugger Fixes  ·  CLS from Cart and Notification Banners  ·  Core Web Vitals on Shopify  ·  CLS in WordPress  ·  Learning Hub

About aiwebpageseo

aiwebpageseo.com is a data-driven SEO and AEO (Answer Engine Optimisation) platform providing a free suite of technical SEO tools. Rather than relying on AI-theorised assumptions, the platform analyses live URL performance, delivering objective diagnostics, page speed metrics, CLS debugging, and site crawl data alongside actionable technical tutorials.