XL
    L
    XS
    M
    S
    XXL
    ← All articles
    Shopify how-to May 9, 2026 11 min read

    How to Add a Size Chart with Metafields in Shopify (Per-Product Charts)

    Different products need different size charts. Metafields are the Shopify-native way to assign one chart per product without copy-pasting into descriptions. Here's the full setup, with code.

    If you sell shirts and pants and shoes, the same size chart can't cover all of them. A "Size M" shirt has a chest measurement; a "Size M" pant has a waist; a "Size 9" shoe has a foot length. Three different categories, three different charts.

    Metafields are how Shopify-native stores attach different data to different products. With one metafield definition, every product gets a "Size Chart" field. You fill in the chart that matches the product type, your theme renders the right chart in a popup, and customers always see the right reference for what they're shopping.

    Why Metafields Beat Other Approaches

    ApproachPer-product charts?EffortMaintainability
    Description HTMLYes (manual copy)Per productLow — search/replace nightmare
    Theme hardcodedNo (one chart for all)Set up onceMedium — survives if you don't upgrade
    Metafield (this guide)Yes (managed centrally)Set up once + per productHigh — Shopify-native, theme-upgrade-safe
    Page reference metafieldYes (charts as Pages)Set up onceHighest — chart edits propagate to all products
    App (Tailor Size Guide)Yes (managed in app)Install + assignHighest — handled by app developer

    Step 1: Define the Metafield (No-Code)

    1. Open Shopify Admin. Go to Settings → Custom data → Products.
    2. Click "Add definition".
    3. Name: "Size chart"
    4. Namespace and key: Click "Edit". Set namespace to sizing, key to chart. Final identifier: sizing.chart.
    5. Type: Choose Rich text (lets you write the chart with formatting in the product editor). Alternative: Reference → Page (lets you point to a Shopify Page; lets multiple products share one chart).
    6. Save. The metafield is now available on every product.

    Rich text vs Page reference

    Use rich text if every product has a unique chart. Use Page reference if multiple products share the same chart (most common — e.g., all your t-shirts use one chart, all your hoodies use another). Page reference is easier to maintain.

    Step 2: Populate the Metafield Per Product

    Open any product in your admin. Scroll to the bottom — you'll see the new "Size chart" field.

    Rich text: Click into the field and write/paste your chart as a table.
    Page reference: Click and select an existing Shopify Page (create one at Online Store → Pages first if needed) that contains the chart.

    Repeat for each product. For Page reference, you'll typically have 3–10 chart Pages total — one per product category — and each product points to its category's chart.

    Step 3: Render the Metafield in Your Theme

    Edit your theme's product.liquid or product-template.liquid. Add this near where you want the size chart button to appear (near the variant picker):

    {% if product.metafields.sizing.chart != blank %}
      <button type="button" class="size-chart-btn" onclick="document.getElementById('size-chart-modal').style.display='flex'">
        Size chart
      </button>
    
      <div id="size-chart-modal" class="size-chart-overlay" onclick="if(event.target===this)this.style.display='none'">
        <div class="size-chart-content">
          <button class="size-chart-close" onclick="document.getElementById('size-chart-modal').style.display='none'">&times;</button>
          <h2>Size Chart</h2>
          <div class="size-chart-body">
            {{ product.metafields.sizing.chart | metafield_tag }}
          </div>
        </div>
      </div>
    {% endif %}

    The Liquid filter | metafield_tag renders rich text properly. If you used the Page reference type instead:

    {% assign chart_page = product.metafields.sizing.chart.value %}
    {% if chart_page %}
      <button type="button" class="size-chart-btn" onclick="document.getElementById('size-chart-modal').style.display='flex'">
        Size chart
      </button>
    
      <div id="size-chart-modal" class="size-chart-overlay" onclick="if(event.target===this)this.style.display='none'">
        <div class="size-chart-content">
          <button class="size-chart-close" onclick="document.getElementById('size-chart-modal').style.display='none'">&times;</button>
          <h2>{{ chart_page.title }}</h2>
          <div class="size-chart-body">
            {{ chart_page.content }}
          </div>
        </div>
      </div>
    {% endif %}

    Step 4: Style the Popup

    Add this CSS to your theme stylesheet (theme.css.liquid or base.css):

    .size-chart-btn {
      display: inline-flex;
      align-items: center;
      gap: 6px;
      padding: 8px 14px;
      background: #fff;
      border: 1px solid #ccc;
      border-radius: 999px;
      font-size: 14px;
      cursor: pointer;
      margin: 8px 0;
    }
    .size-chart-overlay {
      display: none;
      position: fixed;
      inset: 0;
      background: rgba(0,0,0,0.6);
      z-index: 1000;
      align-items: center;
      justify-content: center;
      padding: 16px;
    }
    .size-chart-content {
      background: #fff;
      border-radius: 12px;
      max-width: 640px;
      width: 100%;
      max-height: 90vh;
      overflow-y: auto;
      padding: 32px;
      position: relative;
    }
    .size-chart-close {
      position: absolute;
      top: 12px;
      right: 16px;
      background: none;
      border: none;
      font-size: 28px;
      cursor: pointer;
    }
    .size-chart-body table { width: 100%; border-collapse: collapse; margin-top: 12px; }
    .size-chart-body th, .size-chart-body td { padding: 8px 12px; border: 1px solid #eee; text-align: left; }
    .size-chart-body th { background: #f7f7f7; }
    @media (max-width: 600px) { .size-chart-content { padding: 20px; } }

    Step 5: Test Across Products

    Test a product with a chart: button visible, popup opens, correct chart shows.
    Test a product without a chart: button should be hidden (the {% if metafield != blank %} check).
    Test mobile and desktop: popup centered, scrollable, close button works.
    Test theme upgrade: save a copy of the file before upgrades.

    Bonus: Bulk-Assign Charts via Bulk Editor

    If you have 50+ products and want to assign the same chart to many of them at once:

    1. Filter products in Admin by collection (e.g., "Tops").
    2. Select all filtered products.
    3. Click "Bulk edit".
    4. Add the metafield as an editable column.
    5. Set the value once and bulk-apply across the selection.

    This works best with Page reference metafields — you set every product in the "Tops" collection to point to the same "Tops Size Chart" Page.

    The App Alternative (5 Minutes)

    Tailor Size Guide manages all of the above through its dashboard:

    Define charts per collection in the app dashboard (Tops, Bottoms, Shoes, etc.).
    Auto-assign by product tag or collection — no per-product editing.
    Migrate existing metafield setups — the app reads pre-existing metafields if present.
    Pre-built popup with mobile-tested CSS.
    $9–29/month for the convenience.

    Both approaches use the same underlying metafield system, so you can start with theme code and migrate to the app later (or vice versa).

    Common Mistakes

    Forgetting the {% if metafield != blank %} check

    Without the check, products without charts still show the button — opening to an empty popup. Bad UX. Always wrap in {% if %}.

    Using inline HTML in metafield without metafield_tag filter

    Without | metafield_tag on rich text metafields, you'll see raw HTML strings. The filter renders them as proper HTML.

    Not deduplicating modal IDs across the page

    If your theme renders multiple products on one page (collection page with quick-view), each product's modal needs a unique ID. Use {{ product.id }} in the ID: id="size-chart-modal-{{ product.id }}".

    Theme upgrade overwrites your changes

    Editing files directly is wiped by upgrades. Either keep the modified theme as a duplicate, or use snippet files (snippets/size-chart-modal.liquid) included via {% render 'size-chart-modal' %}. Snippets often survive upgrades better than direct file edits.

    FAQs

    What are metafields in Shopify?

    Custom fields attached to Shopify resources (products, collections). Free and built-in.

    Why use metafields for size charts?

    Reusability and theme-rendering control vs description HTML.

    Can I assign different size charts to different products?

    Yes — that's the main use case for metafields.

    Do I need a developer for metafields?

    Defining is no-code. Theme rendering needs basic Liquid.

    Will metafield size charts slow down the store?

    No — negligible impact.

    Can apps like Tailor Size Guide use metafields?

    Yes — they manage them automatically.

    Pick a Path: Code or App

    If you have a developer and 50+ products with 5+ chart types: go theme code + metafields. If you don't have a developer or you want to ship today: install Tailor Size Guide and assign charts in the dashboard. Both produce the same customer experience.

    For the simpler one-chart-for-all approach, see how to add a size chart popup to Shopify. For the broader Shopify product-page sizing strategy, see how to add a size chart to a Shopify product page.

    Skip the metafield setup — use Tailor Size Guide.

    Per-collection charts, automatic assignment by product tag, mobile-tested popup, no theme code edits.