Explainer 8 min read

preview_theme_id: How Shopify Theme Preview Links Really Work

Your client says the new template is broken. It isn’t — they clicked a link and the preview parameter didn’t come with them. Here is what these URLs actually do.

TS
ThemeSync Team
WHY THE CLIENT SEES THE OLD DESIGN AFTER ONE CLICK1You send the link/products/variety-pack?preview_theme_id=123&view=bundlecorrect template2Client opens itNew bundle templaterenders on the realproduct. Looks right.looks right3Client clicks aproductpreview_theme_id carriesover in-session.view=bundle does not.view dropped4"It’s broken"Default product templaterenders. Client reportsthe redesign as missing.false bugpreview_theme_id survives navigation. ?view= does not.

The two parameters that do all the work

Shopify theme previewing comes down to two query parameters that get confused constantly, because they look similar and do completely different things.

ParameterWhat it selectsSticky across clicks?
preview_theme_idWhich theme renders the pageYes — for the rest of the session
viewWhich alternate template renders this resourceNo — one request only

preview_theme_id selects the theme

Add it to any storefront URL and Shopify renders that page with the theme you named instead of the live one:

Preview a theme on the homepage
https://client-store.myshopify.com/?preview_theme_id=123456789

Shopify sets a session cookie from that first request, which is why the client can then browse the whole storefront and keep seeing your theme. This is the part that works well.

view selects an alternate template

Shopify themes support alternate templates — product.bundle.json, page.lookbook.json, collection.sale.json. Normally a template only renders when a merchant assigns it to a specific product or page in the admin. ?view= lets you force it without assigning anything:

Force an alternate template on one page
# Render product.bundle.json for this product, on theme 123456789
https://client-store.myshopify.com/products/variety-pack?preview_theme_id=123456789&view=bundle

# Render page.lookbook.json for this page
https://client-store.myshopify.com/pages/about?preview_theme_id=123456789&view=lookbook
The asymmetry is the whole problem: the theme choice persists via cookie, the template choice does not. One is a session, the other is a single request.

The false bug this creates in every review round

Here's the sequence that eats an afternoon roughly once per project.

You've built a new bundle template. You send the client a link with ?view=bundle. They open it and it looks great. Then they do the thing any reasonable person does during a review: they click another product to check it there too.

That click goes to /products/some-other-thing with no view parameter. Shopify renders the default product template — correctly, on your theme. The client sees the old design and reports that the new template has stopped working, or works "only sometimes."

You now spend an hour proving a bug that doesn't exist. Worse, if the client has already told their own stakeholder the redesign is broken, you're doing that in public.

Why "just resend the link" isn't a fix: the client will click again. Any review process that depends on the reviewer not navigating is going to fail, and it will look like your build failed rather than your link.

The related trap: sending the wrong resource

?view=bundle on a product that isn't a bundle renders your bundle template with unrelated product data — wrong images, wrong price, wrong copy length. Technically the template is fine. To the client it looks like a broken page, and their feedback will be about content problems you can't fix because they aren't real.

Preview each template on the page it actually applies to

The durable fix is to stop relying on ?view= as the mechanism a client experiences, and instead review each template on a resource where that template is genuinely the right one.

TWO WAYS TO SEND A TEMPLATE FOR REVIEWBARE ?view= LINKfragile✗Template disappears on the first click✗Often shows unrelated product data✗Client reports false bugs✗A new link for every template, every round⚠No indication of what is in scopeMAPPED TO REAL PAGESdurable✓Each template opens on a resource it fits✓Real products, real copy, real images✓Navigation stays on your theme✓One review index, reused every round✓Client can see exactly what to review

In practice that means keeping a deliberate list: this template, that URL. product.bundle previews on the actual variety pack. page.lookbook previews on the real lookbook page. collection.sale previews on the sale collection. When you know the real URLs, the preview link stops being a trick and starts being a page.

Give them an index, not a pile of links

Instead of pasting six URLs into an email, hand over one link that lists the templates in scope with a short label for each. That does three things a list of raw URLs can't: it tells the client what's in scope, it survives across revision rounds, and it means you're never asked to reissue links.

Set expectations in one line. "Open each card from this page — if you navigate away and something looks like the old design, come back to the index rather than clicking around." That sentence prevents most false bug reports on its own.

Other things that break preview links

Password-protected storefronts. If the store isn't launched, the client hits the password gate before they see anything. Send the storefront password in the same message — the round trip to ask for it costs you a day.

Shopify's own share-preview links are time-limited. The share link generated from the admin expires on Shopify's schedule, not your project's. Fine for a one-off look, unreliable as the link you put in a statement of work.

Cookies and stale sessions. Because preview_theme_id sets a session cookie, a client who previewed an older theme last week can land on the wrong one. If someone reports seeing an old build, have them open the link in a private window before you investigate anything else.

Apps and scripts behave differently. Some apps only inject on the published theme, so a preview can legitimately be missing a widget that will appear live. Worth saying up front so the client doesn't log it as a bug.

Analytics pollution. Client review traffic on the real storefront lands in the merchant's analytics. Usually negligible, occasionally worth mentioning to a data-sensitive client before they notice a spike.

Client says…Most likely causeCheck first
"The new design is gone"Navigated away, view droppedReopen from the review index
"It looks like the old version"Stale preview cookiePrivate window
"It asks for a password"Storefront password enabledSend the password
"The reviews widget is missing"App only injects on the live themeConfirm app behaviour
"The product is wrong"view forced onto an unrelated resourceMap to a real matching page

How ThemeSync handles preview links

  • Template mapping stores the real URL for each template. Using read-only Admin API access, you pick the actual product, collection, page or article a template applies to, so previews render on representative pages instead of arbitrary ones.
  • Preview links are generated with both parameters correct. Each mapped template produces a URL combining the theme id and the right view for that resource — no hand-assembled query strings.
  • Clients get one review portal, not a pile of links. A single page lists every template in scope with labels and page types, so the client always has a way back when navigation drops them onto a default template.
  • The link is stable across revision rounds. Because it points at the theme rather than a snapshot, the same URL keeps working as you push changes.
  • It works on development themes. Nothing has to be published, and no draft copy of your source has to sit in the client's admin for a review to happen.

Takeaways

  • preview_theme_id chooses the theme and persists for the session. view chooses the template and lasts exactly one request.
  • That asymmetry is why clients report the redesign as broken after a single click. It's a link problem, not a build problem.
  • Forcing ?view= onto an unrelated product produces feedback about content issues that aren't real.
  • Preview each template on a resource it genuinely applies to, using real store data.
  • Hand over one review index rather than a list of URLs, and say what to do if a page looks wrong.
  • Send the storefront password up front, and reach for a private window before debugging "it looks old."

Preview links your client can’t accidentally break

ThemeSync maps every template to the real page it applies to and gives clients one review portal that keeps working across revision rounds — all on a development theme.

Try ThemeSync Free →