Split Test Pro
Intermediate 5 min read

Shopify Theme App Extension

How Split Test Pro's Theme App Extension injects variant CSS and JS into your storefront — what it adds to the page, how to verify it's active, and how it survives theme changes.

This is a Shopify-only doc. The Theme App Extension is what physically applies variant CSS and JS to your storefront pages. The other half of the Shopify integration — tracking events and attributing conversions — is the Web Pixel.

What the Extension Does

When you install Split Test Pro from the Shopify App Store, Shopify auto-installs the Theme App Extension on your store. The extension adds a single block to your theme: a <script> tag injected into the storefront’s <head> that:

  1. Reads the visitor’s experiment cookie (or assigns a new variant if they haven’t been bucketed yet).
  2. Fetches your active experiments from the Split Test Pro API.
  3. Determines which experiments target the current page.
  4. Applies the relevant variant’s CSS and JS, synchronously, before the page paints.
  5. Fires a split_test_pro_experiment_activated event for the Web Pixel to pick up.

This all happens in milliseconds, before the visitor sees the page. There’s no flicker or flash of the original content.

Auto-Embedding

When the app is installed, the extension’s block is automatically embedded in your published theme via Shopify’s app-blocks system. There’s no manual “drag-and-drop into the theme editor” step.

To confirm the extension is active:

  1. In your Shopify admin, go to Online Store → Themes.
  2. On your live theme, click Customize.
  3. In the left sidebar, click the App embeds icon (puzzle-piece, near the bottom).
  4. Find Split Test Pro in the list. The toggle should be on.

If the toggle is on but variants still aren’t applying, check that the Web Pixel is also connected (see Troubleshooting below).

Where the Extension Lives

For developers and theme inspectors:

  • Asset path: /assets/experiment.js (minified) and /assets/experiment.src.js (source) inside the extension package.
  • Block target: head (injected into <head> of every storefront page).
  • Block file: experiment.liquid — single block defining the script tag.

In your storefront’s rendered HTML, you’ll see a tag like:

<script src="/cdn/shop/extensions/{extensionId}/assets/experiment.js" defer></script>

Custom Theme Compatibility

The extension uses standard DOM APIs (document.head.appendChild, document.cookie, localStorage) and does not depend on jQuery, Liquid context, or any specific theme architecture. It works the same way on:

  • Shopify’s first-party themes (Dawn, Refresh, Craft, Ride, etc.)
  • Headless or hybrid themes
  • Heavily customized themes
  • Themes from third-party marketplaces (Out of the Box, Pixel Union, etc.)

The one place themes can break the extension is CSS specificity: a theme that loads its own stylesheets after the extension or uses inline style="..." attributes can override variant CSS. See CSS Variants for the specificity escape hatches.

What the Extension Adds to Your Page

Visitors won’t notice it; theme inspectors will see:

  • One <script> tag in <head> (the extension itself).
  • One or more <style data-splittestpro-experiment="css"> tags in <head> for any active CSS variants on this page.
  • One or more <script data-splittestpro-experiment="js"> tags in <body> for any active JS variants on this page.
  • A splittestpro-experiment cookie storing the visitor’s variant assignment(s).
  • A splittestpro-visitor cookie + localStorage entry storing the visitor identifier (used as the deterministic seed for variant assignment).

A small floating preview bar may also appear briefly when the merchant has a preview cookie set (used during pre-launch QA). It doesn’t render for normal visitors.

How Theme Changes Affect It

A few common theme operations and what they mean for the extension:

  • Editing your live theme — extension stays active. Edits don’t disable embeds.
  • Duplicating your theme — duplicate starts with App embeds OFF. Re-enable before publishing the duplicate.
  • Switching to a different theme (e.g., installing a new theme version) — the new theme starts with App embeds OFF. Re-enable.
  • Publishing a draft theme — same: App embeds need to be on for the draft before publish.
  • Reverting to a backup theme — the backup’s App embeds state is whatever it was at the time of backup. May or may not be on.

The shorthand: whenever you swap which theme is published, verify App embeds is on for the new published theme.

Troubleshooting

Variants don’t apply at all

  1. Check App embeds is enabled for the published theme (see “Auto-Embedding” above).
  2. Check the script is loading. Open the storefront in DevTools → Network. Filter for experiment.js. You should see a 200 response.
  3. Check for console errors. A theme JS error early in load can interrupt the extension. Open DevTools → Console and look for red errors.
  4. Check the API endpoint is reachable. In Network, look for a POST to /api/experiment/list or similar. A 401 or 500 here means the extension can’t fetch experiments.

Variants apply on some pages but not others

Likely a URL targeting issue, not an extension issue. Use the Preview URL banner in the experiment to confirm targeting matches the page.

Variant CSS shows briefly then disappears

The theme’s stylesheets are loading after the extension and overriding. Use !important or repeated class names to win specificity — see CSS Variants.

Layout shifts when the variant applies

Variant CSS that changes element sizes can cause CLS (cumulative layout shift). Mitigate by:

  • Pre-allocating space in the variant CSS (e.g., set min-height before the change applies).
  • Avoiding large structural changes via CSS — use a redirect test for full-page redesigns instead.

Performance Impact

The extension is small (~10KB minified) and loads defer so it doesn’t block page render. The synchronous variant injection step runs after the script loads but before paint, adding 1-3ms in typical scenarios.

For visitors not in any experiment, the script does the cookie check + API fetch + “no targeted experiments here” no-op and exits — typically under 50ms total, none of it blocking visible render.

Next Steps

Ready to start testing?

Install Split Test Pro and run your first experiment today.

Install on Shopify