How to Test Shopify Theme Changes with Screenshot Comparisons
Preview Shopify theme changes safely, capture consistent before-and-after screenshots, and combine visual review with Theme Check before publishing.
To test Shopify theme changes with screenshot comparisons, preview the work on a development or unpublished theme, capture the same pages at the same viewport and interaction state before and after the change, then inspect the images for unintended visual differences. Run Shopify Theme Check as well: screenshots reveal rendered problems, while Theme Check catches classes of Liquid and JSON issues that a visual review cannot.
Keep the live theme published while you review. Shopify supports development and unpublished theme previews; screenshot comparison is a practical review method, not a Shopify-mandated test protocol.
1. Choose a safe theme preview
Use one of these workflows:
- Local development: run
shopify theme dev. Shopify CLI previews the local theme through a development theme and can hot reload CSS and section changes or refresh the page when files change. Development themes are temporary and Shopify says they are deleted after seven days of inactivity. If the preview needs to remain available after logging out, push the development theme to an unpublished theme. See Shopify CLI for themes. - Theme library: add or use an unpublished theme, then preview it. Shopify documents previewing and sharing unpublished themes, including copies used to test changes. Only one theme can be published at a time. See Adding, previewing, and buying themes.
For local work, install and authenticate Shopify CLI using Shopify’s current instructions, open the theme project directory, and run:
shopify theme dev
Open the preview URL printed by the command. To preserve a development preview as an unpublished theme, use Shopify CLI’s push workflow and follow the prompts for the target store and theme. Confirm the candidate is still unpublished in the Shopify admin before sharing it.
Preview limitations matter: Shopify cautions that a local development preview cannot preview checkout customizations. Review checkout-related work through an appropriate supported workflow rather than assuming a storefront preview proves checkout behavior.
2. Select pages and states that exercise the change
Build a small capture matrix from the code you changed. Shopify does not prescribe a page list; choose representative routes and states based on the theme areas affected.
| Change area | Useful pages or states to capture |
|---|---|
| Header, navigation, global CSS | Home, collection, product, and a narrow viewport with the menu open |
| Product template or product section | Products with different image counts, option counts, sale prices, and availability states |
| Collection cards or filters | A populated collection, a long collection, and filters or sorting open if affected |
| Cart drawer or cart page | Empty cart and cart with items; test the interaction that opens the cart |
| Footer or page sections | A representative long page and the bottom of the page |
| Responsive layout | Desktop and mobile widths, plus any breakpoint where the layout changes |
Do not capture every URL by default. Include templates touched by the change and storefront states where a defect would matter. Use the same product, collection, cart contents, and interaction state in both versions wherever possible.
3. Capture a stable before-and-after baseline
- Choose a published-theme page as the baseline and the corresponding candidate-theme page as the after-change capture. Keep both captures close in time to reduce unrelated content changes.
- Record the URL or template, viewport width and height, browser conditions, and interaction state for each image.
- Use the same browser zoom, device scale, logged-in state, cart contents, and consent state. Wait for fonts, images, and layout shifts to settle before capturing.
- Capture at least one desktop and one mobile size when the change affects responsive styling. Add an intermediate width if a breakpoint is involved.
- Name files so they pair clearly, for example
product-desktop-before.pngandproduct-desktop-after.png.
For a reproducible local setup, a browser automation tool such as Playwright can open two preview URLs and save screenshots. The following runnable Node.js example uses Playwright’s documented screenshot API. Install Playwright and its browser once with npm install -D playwright and npx playwright install chromium, then save this as compare.mjs:
import { chromium } from 'playwright';
const beforeUrl = process.env.BEFORE_URL;
const afterUrl = process.env.AFTER_URL;
if (!beforeUrl || !afterUrl) {
throw new Error('Set BEFORE_URL and AFTER_URL to the two preview page URLs.');
}
const browser = await chromium.launch({ headless: true });
const page = await browser.newPage({
viewport: { width: 1440, height: 1000 },
deviceScaleFactor: 1
});
try {
for (const [name, url] of [['before', beforeUrl], ['after', afterUrl]]) {
const response = await page.goto(url, { waitUntil: 'networkidle', timeout: 60000 });
if (!response || !response.ok()) {
throw new Error(`${name} navigation failed: HTTP ${response?.status() ?? 'no response'}`);
}
await page.evaluate(() => document.fonts.ready);
await page.screenshot({ path: `${name}.png`, fullPage: true, animations: 'disabled' });
}
} finally {
await browser.close();
}
Run it with the preview URLs in environment variables, quoting each URL if it contains shell-special characters:
BEFORE_URL='https://published-preview.example/path' AFTER_URL='https://candidate-preview.example/path' node compare.mjs
Replace the example URLs with the actual preview URLs Shopify provides. If navigation waits indefinitely because the storefront keeps network connections open, use a supported wait condition such as domcontentloaded, then wait explicitly for the selector that marks the page content as ready. Avoid arbitrary long sleeps where a page-specific readiness check is available.
4. Compare images and classify differences
View the pair side by side or use a semi-transparent overlay or pixel difference image. Align the viewport and page position first. Review for:
- Missing or duplicated content, including sections and product cards
- Unexpected shifts in header, navigation, columns, or page width
- Horizontal overflow, clipped text, or controls outside the viewport
- Spacing, typography, line wrapping, colors, and borders that changed unintentionally
- Image crops, aspect ratios, and lazy-loaded images that did not appear
- Mobile navigation, buttons, filters, and other interactive states
For each difference, mark it as intended, defective, or uncertain. Pixel changes are evidence to inspect, not automatic failures: prices, inventory, recommendations, rotating content, timestamps, and other dynamic regions may change independently of the theme. Capture stable content where possible, or treat known dynamic regions separately. An overlay can make alignment errors obvious, but it cannot decide whether a design change is correct.
5. Run code checks alongside visual review
Run Shopify Theme Check on the candidate theme. Shopify describes it as a Liquid and JSON linter that can find syntax errors, missing templates, unused variables and snippets, unknown or deprecated tags, and performance issues. It can run through Shopify CLI on demand or in CI. See Theme Check documentation.
shopify theme check
Resolve findings that apply to the change and review warnings in context. A clean lint result does not prove the rendered page is visually correct, and a screenshot does not expose every code or performance issue. Shopify also describes using Lighthouse against a development-store preview link in its theme testing article; performance testing complements, rather than replaces, the visual comparison.
6. Share and retain the reviewed candidate
When another person needs to review the work, share the unpublished-theme preview link where appropriate. Include the pages and viewport sizes captured, the intended changes, and any remaining dynamic differences. Keep the candidate unpublished until visual and functional review is complete. Shopify documents preview links for unpublished themes, and only one theme can be published at a time.
Or skip the browser setup
ScreenshotNeo is a website screenshot API and MCP server. Give it a URL in one request to get an image or PDF. Its API documentation covers the request options, including viewport configuration and image formats. For a public preview URL, a direct capture looks like this:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Replace the example target with a publicly accessible Shopify preview URL. The service can also capture a selected element, full pages with lazy images loaded, and specific device or viewport configurations, which helps keep paired captures consistent. For private previews, use the documented authentication and custom-header or cookie options as appropriate; do not put secrets in shared scripts or public links.
Cookie and consent banners are accepted as a visitor and removed before capture, along with supported newsletter popups and chat widgets. Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed; response headers report the page verdict and billing status. An MCP server lets AI agents use take_screenshot, get_page_info, and capture_pdf. The free plan includes 1,000 screenshots a month with no card, and paid plans start at $5 for 3,000 shots. Sign up for 1,000 free screenshots a month, with no card required.
Troubleshooting
| Problem | Likely cause | What to do |
|---|---|---|
| Candidate preview shows old styling | The edited file was not saved, the dev server is not serving the expected theme, or cached assets are displayed. | Confirm the CLI points to the intended store and theme, check the terminal for sync errors, reload the preview, and verify the changed asset is served. |
| Preview link is unavailable | A temporary development theme may have expired after inactivity, or the shared unpublished preview link may no longer be valid. | Restart local development or push the candidate to an unpublished theme and create a fresh preview link. |
| Screenshots differ on every run | Dynamic data, animations, delayed fonts, image loading, consent state, or inconsistent viewport settings. | Hold conditions steady, wait for fonts and a page-specific ready selector, disable animations where possible, and annotate genuinely dynamic content. |
| Full-page capture cuts off lower sections | Lazy-loaded content may need scrolling or additional time to render. | Use a capture method that loads lazy images, or scroll through the page and wait for content before saving. |
| Automation times out at network idle | Persistent network activity prevents the browser from reaching the network-idle state. | Use domcontentloaded and wait for a stable page selector instead; keep a finite navigation timeout. |
| Images do not align between captures | Different viewport, device scale, content, or image crop behavior. | Set identical viewport dimensions and scale, use the same page data, and check image sizing rules at each breakpoint. |
| Checkout changes are absent from the local preview | Shopify says local development preview cannot preview checkout customizations. | Use a supported checkout review workflow and treat storefront screenshots as insufficient evidence for checkout behavior. |
| Theme Check reports issues but the screenshot looks fine | Lint checks code structure and known patterns beyond what is visible in one rendered page. | Inspect each finding and correct applicable Liquid or JSON issues; visual appearance alone does not clear a code warning. |
Performance, reliability, and cost
- Capture cost: local browser automation has no per-screenshot API charge, but it uses compute and requires browser setup and maintenance. A hosted screenshot API may charge according to its plan and billing rules; check the provider’s current terms before automating large runs.
- Time: full-page captures and network-idle waits take longer than capturing a viewport after a specific readiness condition. Capture only pages and states that cover the change.
- Reliability: reproducibility depends on identical URLs or equivalent page data, viewport, browser conditions, consent state, and interaction steps. Store the capture matrix with the review so another developer can repeat it.
- Coverage: screenshots cover rendered states, not every interaction or backend behavior. Pair them with functional checks and Theme Check. Shopify’s development preview lifecycle and checkout limitation should be included in the review plan.
The research for this workflow provides no relevant published benchmark or numeric accuracy statistic; there is no basis here for claiming a particular time saving or comparison accuracy.
FAQ
Can I test a theme change without publishing it?
Yes. Shopify supports development themes and unpublished-theme previews so you can inspect a candidate while the current theme remains published.
Does a screenshot comparison replace Theme Check?
No. Screenshots reveal visual output. Theme Check identifies Liquid and JSON issues that may not appear in the captured pages.
How many pages should I capture?
Capture the templates and responsive states affected by the change, plus representative pages that exercise shared components. The right set depends on the change; Shopify does not prescribe a fixed matrix.
Can I use a local preview for checkout customizations?
Shopify cautions that local development previews cannot preview checkout customizations, so use an appropriate separate review path for checkout work.


