Author: [email protected]

  • Does your homepage slider actually convert? What we found in 400 stores

    Does your homepage slider actually convert? What we found in 400 stores

    Every few months someone declares the homepage carousel dead. Then you look at the top 100 Shopify stores in almost any category and most of them still have one. Both things can be true: sliders as they are usually built waste attention, and a slider is still the fastest way to give a homepage a point of view.

    We pulled anonymised engagement data from 400 storefronts running Slidify and looked at what people actually do with slides. Here is what the numbers say.

    Slide one does almost all the work

    Across the sample, the first slide accounted for 81% of all slider clicks. Slide two took 12%. Everything from slide three onward split the remaining 7%.

    That is not a surprise on its own — first position always wins. What surprised us is how little the auto-advance interval moved the number. Stores rotating every three seconds and stores rotating every eight seconds had nearly identical distributions. Shoppers were not waiting for the carousel to show them something better. They were deciding within a second or two whether the hero was relevant, and then either clicking it or scrolling past it.

    The practical read: if your best offer is on slide four, it does not exist.

    Manual advance is a strong intent signal

    Only 6% of sessions touched a slider control at all. But sessions that did convert at roughly 2.3× the rate of sessions that did not.

    This is correlation, not a lever you can pull — people who swipe a carousel were already engaged. It does tell you something useful though: the small group who interact deliberately are worth serving well. Make the dots big enough to hit on a phone, make swipe feel native, and never trap someone in an auto-advance that yanks the slide out from under them mid-read.

    We now pause auto-advance permanently after the first manual interaction. Engagement on those sessions went up, not down.

    The three-slide rule

    Stores that cut their sliders to three slides or fewer saw a small but consistent lift in homepage click-through — about 4% relative in our sample — compared with stores running five or more.

    The mechanism is boring: fewer slides means each one gets more consideration, and the ones that survive the cut tend to be the strongest. It also means less imagery to load, which brings us to the part nobody wants to hear.

    The real cost is usually weight, not attention

    The median slider app in the Shopify ecosystem ships somewhere north of 180KB of JavaScript before it loads a single image. Add three or four uncompressed hero images at desktop resolution served to a phone and you have comfortably pushed your Largest Contentful Paint past the point where Google stops being kind about it.

    We have watched stores gain a full second of LCP by doing nothing more than replacing a heavy slider with a light one and setting proper responsive image sizes. No design change, no copy change, no offer change.

    If you want a single number to check today: open your homepage in Chrome DevTools, throttle to Slow 4G, and look at how long the hero image takes to paint. Anything over 2.5 seconds is costing you.

    What we would do with a homepage slider

    If we were setting up a store from scratch tomorrow:

    1. Three slides maximum. Best offer first, always.
    2. Server-render slide one. It should be in the HTML, not injected by JavaScript after hydration. This is the single biggest LCP win available.
    3. Art-direct for mobile. A 2400px-wide desktop hero cropped down to a 390px phone screen usually loses the product and the text. Set a separate crop and a shorter headline.
    4. Reserve the space. Declare the aspect ratio so the layout does not jump when the image arrives. Cumulative Layout Shift is the easiest Core Web Vital to fix and the most commonly ignored.
    5. Pause on interaction, respect reduced motion. Both are one line of code and both are the right thing to do.
    6. Put one thing below it. A slider with nothing underneath teaches people the page is the slider. Give them a reason to scroll.

    The honest conclusion

    A homepage slider is not a conversion tactic. It is a layout. Whether it helps depends almost entirely on whether slide one is a good hero and whether the implementation is fast enough that people see it before they leave.

    The stores in our data that did best with sliders were not the ones with the most slides or the cleverest transitions. They were the ones where the first slide said something specific, loaded quickly, and led somewhere useful.

    That is a lower bar than most slider apps clear, which is roughly why we built Slidify.

  • Core Web Vitals for Shopify: a practical fix list

    Core Web Vitals for Shopify: a practical fix list

    Most Core Web Vitals advice for Shopify is either “install a speed app” or a wall of theory. This is the middle version: what each metric means for a storefront, and the specific changes that move it, ordered by impact.

    Before you start, get real numbers. The Shopify speed score in your admin is a lab test on a synthetic device — useful for spotting regressions, useless for knowing what your customers experience. Use the Chrome UX Report data in PageSpeed Insights, which reflects real visits to your store over the previous 28 days.

    LCP — Largest Contentful Paint

    What it measures: how long until the biggest thing above the fold has painted. On almost every Shopify homepage this is the hero image. On a product page it is usually the main product photo.

    Target: under 2.5 seconds for 75% of visits.

    Fixes, in order of payoff

    1. Stop lazy-loading your hero. This is the most common own-goal in Shopify theming. loading="lazy" on the LCP image tells the browser to deprioritise the one thing the metric measures. Your hero should be loading="eager" with fetchpriority="high". Everything below the fold should be lazy.

    2. Serve an image sized for the device. A 2400px hero delivered to a 390px phone is roughly 30× more pixels than needed. Shopify’s image_url filter with a proper srcset and a correct sizes attribute solves this:

    {% assign img = section.settings.hero_image %}
    <img
      src="{{ img | image_url: width: 1200 }}"
      srcset="{{ img | image_url: width: 480 }} 480w,
              {{ img | image_url: width: 800 }} 800w,
              {{ img | image_url: width: 1200 }} 1200w,
              {{ img | image_url: width: 1800 }} 1800w"
      sizes="(min-width: 1024px) 100vw, 100vw"
      width="{{ img.width }}"
      height="{{ img.height }}"
      loading="eager"
      fetchpriority="high"
      alt="{{ img.alt | escape }}">

    The sizes attribute is the part people get wrong. If it does not describe the real rendered width, the browser picks the wrong candidate and all the work above is wasted.

    3. Preload the hero. One line in theme.liquid, inside the {% if template == 'index' %} branch so you are not preloading a homepage image on every page.

    4. Audit your app scripts. Open DevTools → Network, filter to JS, sort by size. Anything over 50KB that is not your theme deserves a question. Apps you trialled and abandoned frequently leave script tags behind — check Online Store → Themes → Edit code for orphaned snippets.

    5. Self-host fonts or use font-display: swap. A render-blocking font request from a third-party origin adds a connection setup you cannot control. If the hero text is the LCP element, this is directly on the critical path.

    INP — Interaction to Next Paint

    What it measures: how long the page takes to visibly respond after a tap or click. It replaced First Input Delay because FID only measured the first interaction and only measured the delay, not the response.

    Target: under 200ms for 75% of visits.

    This is the metric Shopify stores fail most often, and it is almost always apps. Every app that adds a global click listener, every chat widget that boots on load, every review widget that re-renders the page — they all compete for the same main thread that needs to handle the tap.

    Fixes

    1. Count your apps honestly. Open your storefront and list every third-party feature on the page. For each one, ask whether it earns its place. The median store we audit is running two apps it forgot it installed.

    2. Defer everything non-critical. Chat widgets, review carousels, popups and analytics should not load during the initial render. Most modern apps support an idle-load or on-interaction mode; a surprising number just do not have it turned on.

    3. Break up long tasks. If you have custom JavaScript doing work over a large collection, chunk it. Anything holding the main thread for more than 50ms is a long task and directly hurts INP.

    4. Watch for layout thrash in sticky headers. Reading getBoundingClientRect() in a scroll handler and then writing a style forces synchronous layout on every frame. Batch reads and writes, or use IntersectionObserver instead.

    CLS — Cumulative Layout Shift

    What it measures: how much visible content jumps around while the page loads.

    Target: under 0.1.

    CLS is the easiest of the three to fix because the causes are finite:

    • Images without dimensions. Always set width and height (or a CSS aspect-ratio). The browser then reserves the box before the file arrives.
    • Web fonts swapping. A fallback font with different metrics reflows the text when the real font lands. Use size-adjust and ascent-override in your @font-face to match metrics, or a tool that generates them.
    • Injected banners. Announcement bars, cookie notices and free-shipping bars that insert themselves at the top of the DOM after paint push everything down. Reserve their height in CSS or render them server-side.
    • Embedded content. Reviews, Instagram feeds and video embeds that expand after loading. Give them a min-height.

    What to do this week

    If you only have an afternoon:

    1. Run PageSpeed Insights on your homepage, a collection page and your best-selling product page. Record the field data numbers.
    2. Fix loading and fetchpriority on your hero image.
    3. Add width and height to every image in your theme that lacks them.
    4. Uninstall one app you are not using, and check the theme code for what it left behind.
    5. Re-measure in 28 days, because field data is a rolling window and will not move overnight.

    That list has, in our experience, moved more stores from red to green than any speed-optimisation app ever has.

    If you want to know what a small app looks like, all six of ours publish their bundle size on their pages. Ours are under 30KB. Most are not.

  • The Shopify product page checklist we run before every launch

    The Shopify product page checklist we run before every launch

    The product page is where the decision happens. Everything upstream — ads, collections, search — only exists to get someone here. This is the checklist we run before any store we work on goes live.

    It is deliberately specific. “Improve trust” is not actionable. “Put the returns window within one scroll of the buy button” is.

    Above the fold

    1. The main image loads first and loads fast. It is the LCP element on almost every product page. Eager loading, high fetch priority, sized for the device.

    2. Price is visible without scrolling on a 375px screen. Test on the smallest phone you support, not on your laptop with DevTools at 375px — those are not the same thing once the browser chrome is included.

    3. The product title reads like a person wrote it. “Merino Crew Neck — Charcoal” beats “MCN-2847-CHR-M Wool Sweater Mens Winter Warm”.

    4. Variant selection is obvious and reflects availability. Out-of-stock variants should look out of stock before they are tapped, not after.

    5. The add-to-cart button says what it does. “Add to cart” is fine. “Submit” is not. If there is a subscription option, the button should change to reflect the selected purchase type.

    6. There is one primary action. A buy button competing with a wishlist button, a compare button and a “notify me” button of equal weight is three ways to not buy.

    Trust and objection handling

    7. Shipping cost and timing are answerable in one interaction. Not a link to a policy page in the footer. A line under the button, or an accordion one tap away.

    8. The returns window is stated in a number of days. “Easy returns” means nothing. “30-day returns, we pay the label” means something.

    9. Reviews are on the page, not in a tab that requires loading. If you have fewer than ten reviews, show them anyway — sparse and real beats absent.

    10. Review content is skimmable. A rating distribution bar and the ability to filter by star rating does more work than a chronological list.

    11. Sizing guidance is specific to this product. A generic size chart for the whole store is a returns generator. Model height and worn size is the single highest-value line of copy on an apparel PDP.

    12. Payment options are shown as icons near the button. This is the one place trust badges genuinely earn their space — people want to know if their preferred method works before they invest in checkout.

    13. Nothing on the page is false. No fake countdown, no invented “12 people are viewing this”, no scarcity that is not real. Shoppers recognise these and the ones who do not are being misled. Neither outcome is good.

    Content and clarity

    14. The first paragraph answers “what is this and who is it for”. Not brand story. Brand story goes further down.

    15. Specifications are in a table, not a paragraph. Materials, dimensions, weight, care. Scannable.

    16. There is at least one image showing scale. A product in isolation on white has no size. Show it held, worn, or beside something familiar.

    17. There is at least one image showing detail. Texture, stitching, finish. This is what replaces touching it.

    18. Alt text describes the image. Both for screen readers and because image search is a real traffic source for physical products.

    Technical and search

    19. Product structured data is valid. Schema.org Product with offerspricepriceCurrencyavailability and aggregateRating where you have reviews. Test it in Google’s Rich Results Test. Rich snippets in search results measurably improve click-through.

    20. The canonical URL is clean. Shopify serves products at both /products/x and /collections/y/products/x. Make sure the canonical points at the former, consistently.

    21. The meta description is written, not generated. 150 characters that give a reason to click, not the first 150 characters of the description.

    22. No layout shift when reviews or badges load. Reserve the space.

    23. It works with JavaScript disabled — or at least degrades honestly. You do not need full no-JS support, but a page that renders as a blank white rectangle when a script fails is a page that loses every visitor on a flaky connection.

    The one that is not on the list

    We deliberately do not include “add urgency” as a checklist item. Real urgency — genuine low stock, a genuine campaign deadline — is worth communicating. Manufactured urgency converts slightly better in the short term and costs you the customer’s trust permanently, which is a bad trade for anyone planning to still be selling next year.

    If you want the honest version of that pattern, build it against your real inventory data rather than a number you type into a settings field. It converts less than a lie would. That is the point.

    Running the checklist

    Print it, or copy it into a Notion doc. Run it on your three best-selling products first — that is where a two-point conversion improvement pays for the afternoon.

    Then run it on a product you have not looked at in a year. That one is usually more instructive.

  • Shopify SEO: collection pages are the pages you are neglecting

    Shopify SEO: collection pages are the pages you are neglecting

    Most Shopify SEO effort goes into product pages and blog posts. Meanwhile the collection page — the one that should rank for “womens merino base layers”, the highest-commercial-intent search in that category — ships as a title, a grid, and nothing else.

    This is backwards. Collection pages are how category searches get satisfied, and category searches are where the money is.

    Why collections outrank products for category terms

    Search for a category term and look at what ranks. It is almost never a single product page. It is category pages, because they match the intent: the searcher wants to compare options, not buy a specific SKU.

    A product page competing for “merino base layers” is competing with one item against pages offering forty. It loses. The collection page is the right page for that query, and on most Shopify stores it is the least developed page on the site.

    What a collection page needs

    An introduction that is genuinely useful

    Not 300 words of keyword-stuffed filler beneath the grid where nobody reads it. Two or three short paragraphs above or beside the grid that help someone choose:

    • What is in this category and how the options differ
    • What to consider when choosing (weight, fit, use case)
    • A pointer to the obvious default for someone who does not want to think

    This copy does double duty. It gives search engines something to understand the page by, and it helps the shopper who is genuinely undecided — who is the person the page exists for.

    Shopify lets you put this in the collection description field. If your theme renders that description in a tiny box under the header, edit the section to give it room.

    A title and meta description written for the query

    The default is {{ collection.title }} – {{ shop.name }}. Do better:

    {%- if collection.metafields.seo.title -%}
      {{ collection.metafields.seo.title }}
    {%- else -%}
      {{ collection.title }} | {{ shop.name }}
    {%- endif -%}

    A metafield gives you per-collection control without touching code again. Write titles that include the qualifier people actually search — “Merino Base Layers for Women | Free UK Delivery” beats “Base Layers”.

    Faceted navigation that does not create a crawl swamp

    Shopify’s filter URLs (?filter.v.option.size=M) can generate thousands of near-duplicate URLs. Google will crawl them, find near-identical content, and spend your crawl budget on it.

    Two things to do:

    1. Make sure filtered views carry a canonical pointing at the unfiltered collection.
    2. Disallow the filter parameters in robots.txt if you are not deliberately targeting the filtered combinations.

    If a specific filtered view does deserve to rank — “black merino base layers” is a real search — do not rely on the parameter URL. Create a real collection for it with its own title, description and canonical.

    Structured data

    Collection pages support CollectionPage and ItemList markup. This is not a ranking factor on its own, but it helps search engines understand the page as a list of products rather than an undifferentiated blob of text.

    {
      "@context": "https://schema.org",
      "@type": "CollectionPage",
      "name": "Women's Merino Base Layers",
      "url": "https://example.com/collections/womens-merino-base-layers",
      "mainEntity": {
        "@type": "ItemList",
        "numberOfItems": 24,
        "itemListElement": [
          { "@type": "ListItem", "position": 1, "url": "https://example.com/products/…" }
        ]
      }
    }

    Internal links that go somewhere

    Related collections, a link up to the parent category, and links down to sub-collections. Most Shopify stores have a flat collection structure with no internal linking between collections at all, which means every collection is an island reachable only from the nav.

    Pagination handled properly

    If your collection paginates, each page needs a self-referencing canonical (not one pointing at page 1 — that has been wrong since Google dropped rel=prev/next support). Page 2 is a different page with different products; treat it as one.

    Infinite scroll needs paginated URLs behind it or the products beyond the first screen are invisible to crawlers.

    The content that actually earns links

    Here is the part most stores skip. The collection pages that outperform are usually the ones with a genuine buying guide attached — not a blog post linking to the collection, but content on the collection page itself.

    For a base layer collection: a short section on the weight ranges and what conditions each suits. For a coffee collection: the roast levels and what they taste like. This is the content that gets linked to, and the links land on the page you want to rank rather than on a blog post two clicks away.

    A realistic order of operations

    You probably have more collections than time. Prioritise:

    1. Find your top 10 collections by revenue. Shopify Analytics → Sales by collection.
    2. Search their primary term and see what ranks. If it is competitors’ collection pages, you have a real opportunity.
    3. Write the intro copy for those 10. Two paragraphs each. One afternoon.
    4. Fix titles and meta descriptions on the same 10.
    5. Add structured data site-wide. It is one theme edit.
    6. Sort out filter canonicals and robots rules. Also one edit, and it protects everything else you do.

    Then leave it for eight weeks. Collection page improvements do not show up next Tuesday; they show up when the page gets recrawled and re-evaluated, which for a mid-sized store is measured in weeks.

    What not to bother with

    • Keyword density. Not a thing. Write for the person choosing.
    • Duplicating the intro copy across collections with the term swapped. Search engines are good at noticing this, and it makes your store worse for humans.
    • Hidden text below the fold. If you are hiding it because it is bad for shoppers, it is not helping.

    Collection pages are unglamorous work. They are also, on most Shopify stores, the largest pile of unclaimed organic traffic available.

  • How to audit app bloat on your Shopify store in 30 minutes

    How to audit app bloat on your Shopify store in 30 minutes

    The average Shopify store runs six apps. The average store we audit is running two it forgot about, one that was uninstalled but left code behind, and one that loads 200KB to display a badge.

    This is the audit we run. It takes about half an hour and you need nothing but a browser.

    Step 1: Inventory what actually loads (10 minutes)

    Open your storefront homepage in Chrome. Open DevTools, go to the Network tab, tick Disable cache, and reload.

    Now:

    1. Filter to JS.
    2. Sort by Size, descending.
    3. Screenshot it.

    You are looking at every script your storefront loads, biggest first. Your theme’s own JavaScript is usually near the top and that is fine. Everything else needs a justification.

    Repeat this on a product page and a collection page. Some apps only load on specific templates, and some load everywhere when they should not.

    What to write down: for each script over 30KB, the domain it came from and its size. The domain tells you the app.

    Step 2: Find the orphans (5 minutes)

    Uninstalling an app in Shopify admin removes its app embed. It does not always remove code that was injected into your theme — particularly for apps installed before app embeds existed, or apps that asked you to paste a snippet.

    In your admin:

    1. Online Store → Themes → ⋯ → Edit code
    2. Open layout/theme.liquid and read the <head> and the bottom of <body> carefully.
    3. Look in snippets/ for files with vendor names you do not recognise.
    4. Search the whole theme for <script src= and for .myshopify.com/apps.

    Anything referencing an app you no longer use is dead weight — often a request that 404s, which is still a request.

    Before you delete anything, duplicate the theme. This is a two-click backup and you will want it.

    Step 3: Check the app embeds you do have (5 minutes)

    Online Store → Themes → Customize → App embeds (the plug icon in the left sidebar).

    Every embed here is loading on every page. Toggle off anything you are not actively using. You do not have to uninstall the app to stop it loading — this is useful for seasonal apps.

    Step 4: Classify each app (10 minutes)

    For every app still standing, put it in one of four buckets:

    Keep as-is. It is small, it is used, it earns its weight.

    Keep but defer. It is used but it does not need to load during the initial render. Chat widgets, review widgets below the fold, popups, loyalty widgets. Check the app settings for a “load on interaction” or “defer” option — many have one that is off by default. If it does not have one, ask support. It is a reasonable request.

    Replace. It does something you need, but there is a lighter option. Sliders, badges, countdowns and popups all have a wide spread of implementation quality — the difference between the heaviest and lightest option in each category is frequently 5–10×.

    Remove. You are not using it, or the feature is not worth the weight. Be honest here. An app that produced a measurable lift when you installed it eighteen months ago may not be earning anything now.

    Step 5: Measure before and after

    Run PageSpeed Insights on your homepage before you change anything and screenshot the result. This is your baseline.

    Make your changes, then re-run the lab test immediately to confirm the direction. Do not expect the field data to move — that is a rolling 28-day window of real visits and it will take about a month to reflect the change.

    What “good” looks like

    For a mid-sized store on a modern theme:

    MetricTarget
    Total JS on homepageUnder 300KB compressed
    Third-party JSUnder 100KB compressed
    Requests to non-Shopify domainsUnder 10
    LCP (field, mobile)Under 2.5s
    INP (field, mobile)Under 200ms

    If your third-party JavaScript is more than your theme’s, you have found your problem.

    The uncomfortable part

    Most stores can remove two apps without anyone noticing. The reason they do not is that each app individually seems defensible — it does something, someone installed it for a reason, removing it feels like a loss.

    The cost is not per-app though. It is cumulative, it is paid by every visitor on every page load, and it is invisible in your admin. Nobody sends you a report saying “your reviews widget cost you 140 sales this month by pushing your INP over 200ms.”

    That is what makes this audit worth thirty minutes a quarter.

    What we do about it

    Every app we build publishes its compressed bundle size on its page, and we treat that number as a product constraint rather than an outcome. It is why our apps do fewer things than the suites they compete with — and why installing three of ours is still lighter than installing one of theirs.

    You can see the numbers on the apps page. Compare them to what you are running now.

  • Seven store design decisions that matter more than your theme

    Seven store design decisions that matter more than your theme

    Merchants spend weeks choosing a theme and an afternoon on everything below. The ratio should be reversed. A well-executed free theme beats a badly configured premium one every time, because these seven decisions do most of the work.

    1. Pick two typefaces and stop

    The fastest way to make a store look amateur is three or more type families. The fastest way to make it look considered is one family used at several weights, or two with an obvious division of labour — one for headings, one for everything else.

    Two practical constraints:

    • Load one weight range, not eight. A variable font covering 400–800 is one file. Eight static weights are eight requests, and you will use three of them.
    • Set a real type scale. Pick a ratio (1.25 is safe) and generate your sizes from it rather than choosing each one by eye. Consistency across a store is what reads as “designed”.

    2. Use one accent colour, deliberately

    Most store palettes fail by having too many colours doing the same job. You need:

    • A background (usually near-white or near-black)
    • A text colour with sufficient contrast against it
    • One accent, used only for things that are clickable or important
    • A muted grey for secondary text

    That is four. If your accent appears on a decorative divider, a heading, a badge and a button, it has stopped meaning “this is actionable”.

    Check contrast properly. Body text needs a 4.5:1 ratio against its background; large text needs 3:1. Grey-on-grey looks refined in a mockup and is unreadable on a phone outdoors.

    3. Set spacing on a scale

    Pick a base unit — 4px or 8px — and use multiples of it for every margin and padding value in the store. This single rule fixes more visual noise than any other change, because inconsistent spacing is what makes a page feel restless without anyone being able to say why.

    Then use spacing to group. Related things sit close together; unrelated things sit far apart. A price 4px from its product title and 32px from the next product reads correctly. The same elements at 16px and 16px do not.

    4. Decide what your images are

    Not “get good photography” — decide on a rule and apply it. Every product on white. Or every product in context. Or a consistent alternation of both. The specific choice matters far less than whether a shopper can tell there was a choice.

    The same applies to crop ratio. Pick one for product cards (4:5 is a good default for apparel, 1:1 for objects) and enforce it. A grid where some images are square and some are portrait looks broken even when every individual photo is good.

    5. Give the header one job

    Your header is not a sitemap. It should contain:

    • Your logo, linking home
    • Between three and six top-level links
    • Search, cart, account

    That is it. If you have eleven categories, the answer is a mega menu or a better information architecture, not eleven links at 13px.

    On mobile, the cart and search must be reachable with a thumb. Test this on a real phone held in one hand, which is how the majority of your traffic will do it.

    6. Write the microcopy

    The small text is where stores leak trust:

    • Empty cart: “Your cart is empty” is fine. Adding “Browse best sellers” with a link is better.
    • Form errors: “Invalid input” is useless. “Enter a postcode like SW1A 1AA” is useful.
    • Button labels: describe the outcome. “Add to cart”, “Continue to payment”, “Apply filters”.
    • Loading states: say what is loading.
    • Out of stock: say when it is back, or offer to tell them.

    None of this needs a designer. It needs someone to read every string on the site once, out loud.

    7. Respect the browser

    The things that make a store feel solid are mostly things you get for free by not overriding them:

    • Focus rings. Do not remove them. Restyle them if you must, but a keyboard user who cannot see where they are cannot check out.
    • Native scrolling. Custom scroll libraries almost always feel worse than the browser’s and break on touch devices.
    • prefers-reduced-motion. One media query. Some of your customers get motion sickness from parallax.
    • Back button. If your filters or variant selection do not update the URL, the back button takes people off the page instead of back a step.
    • Text selection and zoom. Do not disable either.

    The through-line

    Every item on this list is a constraint, not an addition. Fewer typefaces, one accent colour, one spacing scale, one image rule, fewer header links, less overridden browser behaviour.

    Good store design is mostly subtraction, which is why it does not correlate well with how much you spent on the theme.

    It is also why we build apps that inherit your theme’s decisions rather than imposing their own. An app that arrives with its own font, its own accent colour and its own spacing scale undoes the work you did here — which is a strange thing to pay a monthly fee for.

  • Urgency without lying: what actually works on a Shopify store

    Urgency without lying: what actually works on a Shopify store

    Scarcity works. That is not in dispute — it is one of the most replicated findings in behavioural research. What is in dispute is whether the version most Shopify stores deploy is scarcity at all, or just a lie with a timer on it.

    The three common fakes

    The resetting countdown. A timer that says the sale ends in 4:59:59, and says the same thing tomorrow. Every returning visitor learns this immediately. So does anyone who opens the page in a second tab.

    The invented visitor count. “17 people are viewing this product.” Generated by Math.random() in a script you can read in DevTools in about ten seconds.

    The fixed stock number. “Only 3 left!” hardcoded in a settings field, showing on a product with 400 units in the warehouse.

    All three raise conversion in an A/B test over two weeks. All three are also visible to anyone technical, memorable to anyone who returns, and — in several jurisdictions — regulated. The UK’s Digital Markets, Competition and Consumers Act and the EU’s Unfair Commercial Practices Directive both cover false urgency claims specifically. The FTC has brought cases on it.

    The reason to avoid them is not primarily legal, though. It is that they are a loan against your reputation with a bad interest rate.

    What honest urgency looks like

    Real inventory

    If you have three left, saying so is not a trick — it is useful information. The implementation detail that matters is that the number comes from your actual inventory, updates when it changes, and disappears when the product restocks.

    Shopify exposes this. product.selected_or_first_available_variant.inventory_quantity is right there in Liquid. The only reason to use a fake number is not having connected the real one.

    A threshold helps. Showing “only 47 left” is not urgent and slightly comic. Set a display threshold — under 10, or under a week of typical velocity for that SKU — and stay silent above it.

    Real deadlines

    Campaign end dates, pre-order cut-offs, and shipping deadlines are all genuinely time-bound. “Order by 2pm Thursday for delivery before the 25th” is the highest-converting urgency message in ecommerce and it is completely true.

    The technical requirement is timezone handling. A deadline that is correct in your timezone and wrong in your customer’s is a support ticket and a refund. Compute against a fixed instant, render in the visitor’s locale.

    Real demand signals

    “This sold out twice last month” — if true — is more persuasive than a fake viewer count, because it is specific and checkable. Same for “back in stock after six weeks”.

    Real recent purchase notifications work too, with two conditions: they must be actual orders, and they must be rate-limited. A notification every four seconds reads as fake even when it is real.

    Real cart reservation

    If your checkout actually holds inventory for ten minutes, saying so is helpful. If it does not, do not say it does — a customer who takes twenty minutes and loses the item will remember the promise.

    The one that is honest and underused

    Restock notifications. Instead of manufacturing urgency around a product someone can buy, capture demand for one they cannot. “Email me when this is back” converts at a rate that embarrasses most popups, costs nothing to run, and produces a list of people with demonstrated intent for a specific SKU.

    Most stores either do not offer it or bury it. It is the single best urgency-adjacent feature available and it requires no ethical compromise at all.

    What the numbers look like

    Published case studies on real-inventory scarcity bars tend to report single-digit lift on add-to-cart rate — meaningfully less than the 15–20% figures quoted in fake-scarcity write-ups.

    That gap is the honest cost. You give up some short-term conversion.

    What you get in exchange is a mechanic that keeps working. Fake scarcity has a decay curve — it converts best on first-time visitors and progressively worse as your returning-customer share grows. Real scarcity has no decay, because there is nothing to see through.

    For a store planning to be around in three years, that is not a close call.

    A short implementation checklist

    • Inventory display driven by real Shopify inventory, with a sensible threshold
    • Countdowns tied to a real campaign end stored as a UTC instant
    • Purchase notifications from real orders, rate-limited, with no invented names
    • Shipping cut-off messaging computed against the customer’s timezone
    • Restock notification capture on every out-of-stock variant
    • Nothing that resets when the page reloads

    Every item on that list is achievable in a theme with no app at all. The work is mostly in wiring the display to your real data rather than to a settings field — which is exactly why so many apps skip it.