Tutorial / Guide 11 min read

Shopify Dev Theme Template Mapping: The Complete Guide

Custom templates on dev themes can't be assigned via Shopify admin. Here's everything you need to know about viewing, mapping, and presenting custom templates to clients.

TS
ThemeSync Team
WITHOUT MAPPING WITH AUTO-MAPPING VS admin.shopify.com / pages / summer-sale Online Store โ€บ Pages Summer Sale Landing Page Theme template Default page template โ–พ โš  Development theme Custom templates can't be assigned to dev themes Preview (dev theme) โ† Default template Not the landing layout boho-boutique.myshopify.com/pages/summer-sale SHOP Summer Sale Up to 40% off ยท Limited time Shop Now ๐Ÿ› โœฆ Landing template rendered correctly via ThemeSync auto-mapping ยท no admin assignment needed โœฆ ThemeSync ยท page.landing.json mapped

Why Template Mapping Is a Problem on Dev Themes

If you've used Shopify CLI for theme development, you know the workflow: create a development theme on the client's production store, iterate on it via shopify theme dev, and preview changes in real-time with actual store data.

This is fantastic โ€” until you create custom templates.

Custom templates (like page.landing.json, product.bundle.json, or collection.seasonal.json) need to be assigned to specific pages or products via the Shopify admin. But here's the catch: dev themes don't appear in the admin's template assignment dropdown.

The core issue: To assign a template to a resource (page, product, collection), the theme must be the "live" theme or at least accessible in the theme editor. Dev/preview themes are invisible to the template selector. You cannot assign templates without publishing.

This means your beautifully crafted landing page template sits there, technically uploaded to the theme, but with no way for a client (or even you) to see it applied to the correct page through normal navigation.

How Shopify Templates Actually Work

Before diving into solutions, let's understand the mechanics. For the full reference, see the Shopify theme templates documentation.

Template Assignment Storage

When you assign a template to a page in Shopify admin, Shopify stores that assignment in the resource's metafield, not in the theme. Specifically:

  • The page/product/collection has a template_suffix field
  • This suffix tells Shopify which template file to render: page.[suffix].json
  • If no suffix is set, Shopify uses the default template (page.json)

How Dev Theme Preview Works

When you visit a dev theme preview URL, Shopify renders the requested page using the dev theme's templates. But it still uses the resource's template_suffix to determine which template to load.

If the page doesn't have a template_suffix assigned (because you can't assign one via admin to a dev theme), Shopify renders the default template โ€” regardless of what custom templates exist in the theme.

The URL Override: ?view=

Shopify provides a URL parameter override: appending ?view=template-name forces a specific template to render. For example:

URL Parameter Template Override
# Forces the "landing" template on any page
https://store.myshopify.com/pages/about?view=landing

# Forces the "bundle" template on a product
https://store.myshopify.com/products/variety-pack?view=bundle

# Combined with dev theme preview
https://store.myshopify.com/pages/about?preview_theme_id=12345&view=landing

This works perfectly for developers. But asking clients to use these links? That's where things fall apart.

The URL Parameter Approach (?view=)

The simplest solution is to send clients a list of links with the correct ?view= parameters pre-applied.

Pros
  • โœ“No additional code or tools needed
  • โœ“Works immediately
  • โœ“Easy to understand technically
Cons
  • โœ—Clients don't use them. ~90% navigate directly via bookmarks or site nav instead.
  • โœ—Links are long, ugly, and confusing to non-technical people
  • โœ—Any page visited without the param shows the wrong template
  • โœ—Internal links don't carry the ?view= parameter forward
Real-world pattern: You send a client 5 links with params. They click the first one, see it looks great, then navigate via the site's menu to the other pages. Those pages render with default templates. Client emails: "Pages 2-5 are broken." Repeat on every project.

This approach works for developer-to-developer reviews. For client-facing reviews, you need something that doesn't require client cooperation.

The Snippet Injection Approach

A more robust approach: inject a Liquid snippet into the theme's layout/theme.liquid that intercepts page loads and applies the correct template based on a mapping configuration.

How It Works

  1. Define a mapping in a JSON file or snippet: "When URL = /pages/about, use template = landing"
  2. The snippet checks the current URL on every page load
  3. If a mapping exists, it redirects to the same URL with the correct ?view= parameter
  4. This happens transparently โ€” the client just visits the page normally
Conceptual Liquid Snippet (simplified)
{% comment %}
  Template auto-mapping โ€” renders correct templates on dev themes
  Mappings defined as: page_url โ†’ template_suffix
{% endcomment %}

{% assign current_path = request.path %}
{% assign view_param = request.page_type %}

{% comment %} Only apply if no ?view= already present {% endcomment %}
{% unless request.design_mode or canonical_url contains 'view=' %}

  {% if current_path == '/pages/about' and template.suffix != 'story' %}
    {% assign target_url = current_path | append: '?view=story' %}
    <script>window.location.replace('{{ target_url }}');</script>
  {% endif %}

  {% if current_path contains '/products/' and product.type == 'Bundle' and template.suffix != 'bundle' %}
    {% assign target_url = current_path | append: '?view=bundle' %}
    <script>window.location.replace('{{ target_url }}');</script>
  {% endif %}

{% endunless %}
Pros
  • โœ“Client navigates normally โ€” correct template loads automatically
  • โœ“No special links or instructions needed
  • โœ“Works with the site's own navigation
Cons
  • โœ—Causes a visible page flash/redirect (URL changes, page reloads)
  • โœ—Requires manual mapping configuration in Liquid/JSON
  • โœ—Must be removed before publishing the theme
  • โœ—Doesn't work well with Shopify's section rendering API

Auto-Mapping: The Best Solution

The ideal approach combines the transparency of snippet injection with a proper management interface and eliminates the redirect flash:

ThemeSync โ€” Template Mapping ยท Boho Boutique Template Mapping Cloud Preview Visual QA Feedback Sign-off Boho Boutique Shopify ยท dev theme #12345 Template Mapping Map custom templates to pages, products & collections โœ“ 7 templates detected Save Mapping TEMPLATE FILE MAPPED TO TYPE / STATUS page .landing.json โ†’ /pages/summer-sale Page โœ“ Mapped product .bundle.json โ†’ tag = "Bundle" conditional ยท 12 products Product โœ“ Conditional collection .seasonal.json โ†’ /collections/summer-2026 Collection โœ“ Mapped page .story.json โ†’ /pages/our-story Page โœ“ Mapped product .subscription.json โ†’ Not yet mappedโ€ฆ Product โš  Unmapped page .faq.json โ†’ /pages/faq Page โœ“ Mapped collection .sale.json โ†’ /collections/sale Collection โœ“ Mapped 6 of 7 templates mapped 86% โš  1 template unmapped

What Auto-Mapping Does

  1. Detects all custom templates in your theme (scans the templates/ directory)
  2. Fetches store content via the Admin API (pages, products, collections)
  3. Lets you map each template to specific resources via a UI
  4. Injects the mapping into the theme as a Liquid snippet that handles routing transparently

Why This Works Better

  • Client visits any page โ†’ sees the correct template
  • Internal navigation works (links between pages maintain correct templates)
  • No client education needed
  • Mapping is managed from a dashboard, not by editing Liquid code
  • Can be removed cleanly before deployment

This is exactly what ThemeSync's Template Mapping feature provides โ€” a visual template mapping interface that auto-detects your templates, shows available store resources, and handles the injection transparently.

Conditional Mapping for Product Types

Some templates should apply conditionally โ€” not to a specific product, but to a type of product. Examples:

  • product.bundle.json โ†’ Any product tagged "Bundle" or in the "Bundles" collection
  • product.subscription.json โ†’ Any product with a selling plan
  • collection.seasonal.json โ†’ Collections with "seasonal" in the handle

Direct vs. Conditional Mapping

TypeUse CaseExample
DirectSpecific page/product gets a specific template/pages/our-story โ†’ page.story
ConditionalAny product matching criteria gets a templateCollection = "Bundles" โ†’ product.bundle

Conditional mapping is powerful for stores with many products of the same type. Instead of mapping 50 bundle products individually, you define one rule: "Any product in the Bundles collection uses the bundle template."

Pro tip: Combine direct and conditional mapping. Use direct for one-off pages (About, Contact, FAQ) and conditional for product/collection types. This mirrors how the store will actually assign templates post-launch.

Presenting Templates to Clients

With auto-mapping in place, presenting templates to clients becomes trivial:

The Client Experience

  1. Client receives a single preview URL
  2. They navigate the site normally (via navigation, search, or direct URLs)
  3. Every page shows the correct template automatically
  4. They leave feedback directly on the page (if using a feedback tool)

No instructions. No special links. No "please use this URL with these parameters." The preview just works like a real website.

Setting Expectations

Even with auto-mapping, set clear expectations with clients:

  • This is a preview โ€” content they add/change in Shopify admin won't appear until go-live
  • Some features (loyalty apps, reviews, etc.) may not be active on the dev theme
  • The URL will look different from their final site URL
  • Design is being reviewed, not content (unless they're also doing content migration)

Common Mistakes and How to Avoid Them

Template mapping is a critical step in a complete theme delivery workflow. The Theme Ops Checklist includes a pre-presentation verification section that covers all the common failure points.

Mistake 1: Forgetting to Remove the Mapping Snippet Before Publish

If your theme contains a template mapping snippet and you publish it, it'll redirect live visitors to ?view= URLs. Always clean up before deployment.

Solution: Use a tool that manages injection/removal automatically. Or wrap the snippet in a condition that only fires on dev theme previews: {% if request.design_mode %}

Mistake 2: Not Mapping ALL Custom Templates

If you map 3 out of 5 templates, clients will navigate to the 2 unmapped pages and see the default template. They'll assume those pages haven't been built yet (or are broken). Map everything.

Mistake 3: Mapping to Wrong Resources

A "landing page" template mapped to the /about page will confuse everyone. Make sure your mappings reflect the actual site structure that will exist post-launch.

Mistake 4: Not Testing the Full Navigation Flow

Test the preview as if you were a client: start at the homepage, click through the navigation, visit products from collections. Every path should land on the correct template.

Mistake 5: Ignoring 404s from App Embeds

If your custom template references app blocks (Klaviyo, Yotpo, etc.) that aren't installed on the dev theme, the page may 404 entirely. Scan for external dependencies before presenting to clients.

ThemeSync โ€” Theme Compatibility ยท Boho Boutique Pre-flight Compatibility Scan Checks app embeds, metafields, and external dependencies before client handoff โ†ป Re-scan โœ“ 5 passed โš  2 warnings โœ— 1 error Scanned 2 min ago ยท dev theme #12345 APP EMBEDS ๐Ÿ“ง Klaviyo Email Marketing theme.extensions/klaviyo ยท blocks: klaviyo-subscribe-form โœ“ Installed & active โญ Yotpo Product Reviews theme.extensions/yotpo ยท blocks: yotpo-reviews-widget โš  App not on dev theme ๐Ÿ”„ Recharge Subscriptions theme.extensions/recharge ยท blocks: rc-subscribe-widget, rc-customer-portal โœ— Causes 404 on render Fix: Install Recharge on dev theme before presenting, or remove rc-subscribe-widget from product.subscription.json METAFIELD DEPENDENCIES ๐Ÿ—‚ product.bundle_contents namespace: custom Used in product.bundle.json ยท liquid: product.metafields.custom.bundle_contents โœ“ Definition exists ๐ŸŽฌ page.hero_video namespace: custom Used in page.landing.json ยท liquid: page.metafields.custom.hero_video โš  No value on /pages/summer-sale

Auto-map templates in 60 seconds

ThemeSync auto-detects your custom templates, shows your store's pages and products, and lets you map everything from a single UI. Clients see the right design on every page โ€” no special links needed.

Try ThemeSync Free โ†’