Keep your theme.
Fix what’s holding it back.

A free deep-dive into the code behind your Shopify theme: what slows it down, what some shoppers can’t use, and what’s quietly broken.

The sweep and report are free. You only pay for changes you choose, from $4 each.

We’re onboarding stores by email ahead of launch. Already testing Bracket? Open the app

Not new sections.
The code underneath them.

Bracket doesn’t redesign your store or add features. It checks that the theme you’ve already invested in loads quickly, works for shoppers using a keyboard or screen reader, stays up to date and keeps working.

Speed

How soon your main image appears, scripts that hold up the page, images far larger than they’re shown, fonts that load late, and pages that jump about as they load.

  • loading="lazy"
  • defer
  • width height
  • font_display

Accessibility

Buttons a screen reader can’t name, form fields without labels, focus you can’t see, text that’s hard to read, and menus a keyboard can’t get out of.

  • aria-label
  • alt
  • :focus-visible
  • <label>

Up to date

Liquid that Shopify has deprecated, filters with newer replacements, and how far you are from your theme’s latest version. On a theme from before Online Store 2.0, we’ll tell you what’s worth updating without pushing you into a rebuild.

  • {% include %}
  • img_url
  • img_tag

Working order

Snippets and files your theme asks for that don’t exist, settings files that won’t parse, and errors that stop a script from running.

  • Liquid error
  • *.json
  • TypeError

A Lighthouse score tells you a page is slow. A sweep points to the line of theme code behind it.

Inside a sweep

We read your theme the way a careful developer would, file by file, and explain what we find in plain English. This is an example theme, not a real store.

ReportExample theme
  1. Your main image waits its turn

    $4

    Speed sections/image-banner.liquid:22

    The banner at the top of your home page is set to load lazily, so the browser fetches it late. It’s the largest thing on screen, so it sets your LCP time.

    Fix: load it first.

    1. {%- liquid
    2. assign image = section.settings.image
    3. assign height = section.settings.image_height
    4. -%}
    5. <div id="Banner-{{ section.id }}" class="banner banner--{{ height }}">
    6. <div class="banner__media media">
    7. {%- if image != blank -%}
    8. <img
    9. src="{{ image | image_url: width: 1500 }}"
    10. loading="lazy"
    11. alt="{{ image.alt | escape }}"
    12. >
    13. {%- endif -%}
    14. </div>
  2. One script holds up every page

    $16

    Speed layout/theme.liquid:10

    vendor.js loads in the head without defer, so nothing on the page appears until it has downloaded and run.

    Fix: defer it, then check everything that uses it.

    1. <!doctype html>
    2. <html class="no-js" lang="{{ request.locale.iso_code }}">
    3. <head>
    4. <meta charset="utf-8">
    5. <meta name="viewport" content="width=device-width,initial-scale=1">
    6. <link rel="canonical" href="{{ canonical_url }}">
    7. <title>{{ page_title }}</title>
    8. {%- render 'meta-tags' -%}
    9. {{ 'base.css' | asset_url | stylesheet_tag }}
    10. <script src="{{ 'vendor.js' | asset_url }}"></script>
    11. <script src="{{ 'global.js' | asset_url }}" defer></script>
    12. {{ content_for_header }}
    13. </head>
    14. <body class="template-{{ template.name }}">
    15. {% sections 'header-group' %}
  3. Your cart’s close button has no name

    $4

    Accessibility snippets/cart-drawer.liquid:7

    It only contains an icon, so a screen reader announces it as “button” with nothing to say what it does.

    Fix: give it a name.

    1. <cart-drawer class="drawer">
    2. <div id="CartDrawer" class="cart-drawer">
    3. <div class="drawer__overlay"></div>
    4. <div class="drawer__inner" role="dialog" aria-modal="true">
    5. <div class="drawer__header">
    6. <h2>{{ 'sections.cart.title' | t }}</h2>
    7. <button class="drawer__close" type="button">
    8. {% render 'icon-close' %}
    9. </button>
    10. </div>
    11. <cart-drawer-items>
    12. {%- for item in cart.items -%}
    13. {%- render 'cart-item', item: item -%}
    14. {%- endfor -%}
    15. </cart-drawer-items>
  4. Product grids jump as they load

    $8

    Speed snippets/card-product.liquid:23

    Product images don’t say how big they are, so the page shifts as each one arrives. Google measures this as CLS.

    Fix: reserve the space.

    1. {%- assign media = card_product.featured_media -%}
    2. <div class="card__inner">
    3. {%- if media -%}
    4. <div class="card__media">
    5. <img
    6. src="{{ media | image_url: width: 533 }}"
    7. alt="{{ media.alt | escape }}"
    8. class="motion-reduce"
    9. loading="lazy"
    10. >
    11. </div>
    12. {%- endif -%}
    13. <div class="card__content">
    14. <h3>{{ card_product.title | escape }}</h3>
    15. {%- render 'price', product: card_product -%}
  5. Liquid that Shopify has retired

    $4

    Up to date sections/header.liquid:59

    Two tags in your header still use include, which Shopify deprecated because it’s slower and harder to maintain. Its replacement is render.

    Fix: update both tags.

    1. {%- liquid
    2. assign menu = section.settings.menu
    3. -%}
    4. <header class="header header--{{ section.settings.logo_position }}">
    5. <a href="{{ routes.root_url }}" class="header__heading-link">
    6. {%- render 'header-logo' -%}
    7. </a>
    8. <div class="header__icons">
    9. {% include 'icon-account' %}
    10. {% include 'cart-icon-bubble' %}
    11. {%- render 'header-search' -%}
    12. </div>
    13. </header>
  6. An app’s script loads on every page

    Advice

    Speed layout/theme.liquid:41

    A reviews app loads its script on every page, including pages with no reviews. It’s the app’s code, so we won’t change it.

    Advice: the report says what to ask the app’s developer.

    1. <main id="MainContent" class="content-for-layout">
    2. {{ content_for_layout }}
    3. </main>
    4. {% sections 'footer-group' %}
    5. {%- render 'cookie-banner' -%}
    6. {{ 'cart.js' | asset_url | script_tag }}
    7. <script src="https://cdn.reviews.example/widget.js"></script>
    8. <script>
    9. window.shopUrl = '{{ request.origin }}';
    10. </script>
    11. </body>
    12. </html>

Sweep complete: 5 changes we could make, and 1 piece of advice. The full report is yours to download, free.

Your report.
Your call.

The report is yours to keep, whether or not you buy anything. Each finding has the file, the line, why it matters and what would fix it. Tick the changes you care about, then take them whichever way suits you.

  • Fix it yourself, or with your developer

    Download the full report as a PDF. It’s written so you can follow it, or a developer can pick it up and price it.

  • Ask your AI assistant

    Download prompt.txt for the changes you’ve ticked and paste it into the assistant you already use.

  • Have us do it

    Each change has a fixed price, agreed before any work starts. We make it on an unpublished copy of your theme, and you publish it.

Choose what changes

Example report and prices
  • Ask the reviews app about its script Advice Free
Download PDFFree Download prompt.txtFree Do the changes for me3 changes for $16

An example report for an example theme. On yours, every price is fixed before you choose, and you approve the total in Shopify.

Free to look.
A fixed price to fix.

Free sweep

$0A deep-dive into your theme, and a report to keep

  • Speed, accessibility, retired code and errors
  • Plain-English findings with the file and line
  • The full report as a PDF, plus prompt.txt for your AI assistant
  • Run it again whenever you like
  • No theme changes and no card details
Request a free sweep

Prices are in US dollars and Shopify handles payment. Paying for a change doesn’t publish anything: you decide what goes live.

Themes drift.
Sweep again.

Your theme doesn’t stay the way you left it. Apps add scripts, Shopify retires code and small edits pile up. A fresh sweep catches what’s changed since the last one.

Run one whenever you like, for free. If you’d like, we’ll email you when it’s time for another.

Questions

Is the sweep really free?

Yes. The sweep and the full report cost nothing, and the report is yours whether or not you buy a change. You only pay for changes you pick.

Will you change my live theme?

No. Bracket makes changes on an unpublished copy of your theme. You preview the result and publish it yourself in Shopify, when you’re happy with it. Bracket never publishes.

My theme is old, or heavily customised. Is that a problem?

No. That’s exactly who a sweep is for, including themes from before Online Store 2.0. We review the theme files Shopify makes available, and if part of your theme can’t be checked, the report says so rather than guessing.

What if a change doesn’t work?

Then you don’t pay for it. Each change comes with checks we agree up front. If it doesn’t pass them, we correct it or refund you.

Can you see my customers or orders?

No. Bracket only asks Shopify for access to your themes. It can’t see customers, orders or payments.

Who makes Bracket?

A team with 16+ years’ experience in the Shopify Theme Store. We’ve spent that time building themes, and looking after them once they’re live.

Start with a free sweep.

Email us your store URL to request one. Nothing changes on your store unless you ask.

Request a free sweep Questions? support@bracket.tools