CheckoutWorks Shopify Partner

We fix Shopify bugs at a flat $49 per fix. Most fixes within 24 hours.

Fix My Bug →

Shopify Horizon: Add a Country-Aware Size Chart Without an App

·Johnny Chen Founder & Shopify Developer at CheckoutWorks
Country-aware size chart in Shopify Horizon showing inches for the United States and centimeters for Germany.

You can add a country-aware size chart to your Shopify Horizon product page without an app using the theme’s built-in popup and a Custom Liquid block. Our chart automatically defaults to centimeters or inches based on the storefront country, and shoppers can switch units at any time.

Below, we share how the pieces fit together, along with the code you can adapt for your own products.

Try the country-aware size guide

Open Size Guide on our demo product page. Switch between CM and inches, or change the storefront country and reopen the guide after the page reloads to compare default units. The same demo product also shows multiple images per color.

Explore the size guide on our live demo →

Shopify Horizon size chart popup showing inches by default for the United States, with a CM/inches switch.

Click Size Guide on the demo page to open a size chart that automatically defaults to centimeters or inches based on the current storefront country.

1. Use Horizon’s popup for the size chart

Horizon provides the popup; the size chart inside it is our custom content. We kept the theme’s existing open-and-close behavior instead of building another modal.

Start on an unpublished duplicate of your theme. Our reference is a customized Horizon 4.1.5 installation, not a guarantee that every version has identical controls or styling.

  1. In the theme editor, open the product template you want to use.
  2. In the product information area, add a Popup link block near the size picker. Set its link text to Size Guide and use the default popup behavior rather than a drawer.
  3. Inside the popup, add a heading such as Size & Fit Guide, followed by a Custom Liquid block.

This keeps sizing information available without displaying the full table on the product page. Our demo also has custom spacing and a ruler icon; those visual details are separate from the size chart logic.

2. Add the size chart and unit switch with Custom Liquid

Custom Liquid is the place where the chart is rendered. HTML holds the measurements, and CSS switches which values are visible. Liquid does not run again when a shopper clicks the unit switch.

For maintainability, we put the chart in snippets/tshirt-size.liquid and render it from the Custom Liquid block. That keeps the editor field short and gives us one place to update the table.

In your duplicate theme’s code editor, create that snippet and add the complete reference code below. If the file already exists, review it before making changes; do not overwrite unrelated content.

{% comment %}Modified by CheckoutWorks.dev{% endcomment %}
{% liquid
  assign iso_code = localization.country.iso_code | default: 'US'
  assign country_name = localization.country.name | default: 'your region'
  assign imperial_countries = 'US,CA,GB,IE,AU,NZ' | split: ','
…
Show full codeCollapse code
{% comment %}Modified by CheckoutWorks.dev{% endcomment %}
{% liquid
  assign iso_code = localization.country.iso_code | default: 'US'
  assign country_name = localization.country.name | default: 'your region'
  assign imperial_countries = 'US,CA,GB,IE,AU,NZ' | split: ','
  assign use_inches = false
  assign default_unit = 'centimeters'
  assign toggle_id = 'sizeguide-unit-toggle-' | append: section.id | append: '-' | append: block.id

  if imperial_countries contains iso_code
    assign use_inches = true
    assign default_unit = 'inches'
  endif
%}
<div class="sizeguide">
  <div class="sizeguide__inner">
    <p class="sizeguide__localization">
      Storefront country: {{ country_name | escape }}
      <span aria-hidden="true">·</span>
      Default unit: {{ default_unit }}
    </p>

    <label for="{{ toggle_id }}" class="toggle__opt">CM</label>
    <input
      type="checkbox"
      id="{{ toggle_id }}"
      {% if use_inches %}
        checked
      {% endif %}
    >
    <span class="toggle__controls"></span>
    <label for="{{ toggle_id }}" class="toggle__opt">INCHES</label>

    <table>
      <thead>
        <tr>
          <th class="size-title">Size</th>
          <th>
            Chest Width
            <span class="default unit-label">(cm)</span>
            <span class="alt unit-label">(inch)</span>
          </th>
          <th>
            Body Length
            <span class="default unit-label">(cm)</span>
            <span class="alt unit-label">(inch)</span>
          </th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>S</td>
          <td><span class="default">45.7</span><span class="alt">18</span></td>
          <td><span class="default">71.1</span><span class="alt">28</span></td>
        </tr>
        <tr>
          <td>M</td>
          <td><span class="default">50.8</span><span class="alt">20</span></td>
          <td><span class="default">73.7</span><span class="alt">29</span></td>
        </tr>
        <tr>
          <td>L</td>
          <td><span class="default">55.9</span><span class="alt">22</span></td>
          <td><span class="default">76.2</span><span class="alt">30</span></td>
        </tr>
        <tr>
          <td>XL</td>
          <td><span class="default">61.0</span><span class="alt">24</span></td>
          <td><span class="default">78.7</span><span class="alt">31</span></td>
        </tr>
        <tr>
          <td>2XL</td>
          <td><span class="default">66.0</span><span class="alt">26</span></td>
          <td><span class="default">81.3</span><span class="alt">32</span></td>
        </tr>
        <tr>
          <td>3XL</td>
          <td><span class="default">71.1</span><span class="alt">28</span></td>
          <td><span class="default">83.8</span><span class="alt">33</span></td>
        </tr>
      </tbody>
    </table>
  </div>
</div>

{% style %}
  .sizeguide {
    width: 100%;
  }

  .sizeguide__inner {
    position: relative;
    width: 100%;
  }

  .sizeguide__localization {
    margin: 0 0 0.75rem;
    font-size: 0.875rem;
    font-weight: 400;
    line-height: 1.4;
  }


  .toggle__opt {
    display: inline-block;
    vertical-align: middle;
    user-select: none;
  }

  .sizeguide input[type='checkbox'] {
    opacity: 0;
    width: 50%;
    position: absolute;
    left: 0;
    cursor: pointer;
    z-index: 99;
  }

  .toggle__controls {
    display: inline-block;
    vertical-align: middle;
    position: relative;
    width: 50px;
    height: 20px;
    margin: 0 10px;
  }

  .toggle__controls:before {
    content: '';
    position: absolute;
    width: 50px;
    height: 2px;
    background: #464646;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
  }

  .toggle__controls:after {
    content: '';
    position: absolute;
    width: 20px;
    height: 7px;
    background: #171717;
    left: 50%;
    top: 50%;
    transform: translate(-130%, -50%);
    transition: transform 0.3s ease-out;
  }

  .sizeguide input[type='checkbox']:checked ~ .toggle__controls:after {
    transform: translate(30%, -50%);
  }

  .sizeguide table {
    width: 100%;
    margin-top: .4rem;
    border-collapse: collapse;
    table-layout: fixed;
  }

  .sizeguide th,
  .sizeguide td {
    text-align: center;
    padding: 12px 5px;
  }

  .sizeguide th {
    background: #1a1a1a;
    color: #fff;
    font-weight: lighter;
    white-space: nowrap;
  }

  .sizeguide td {
    border: 1px solid #d2d2d2;
  }

  .sizeguide thead td {
    border: 0;
  }

  .sizeguide thead .size-title {
    width: 5em;
  }

  .sizeguide td:first-child {
    border-left: 0;
  }

  .sizeguide td:last-child {
    border-right: 0;
  }

  .sizeguide tr:nth-child(2n) {
    background: #f3f3f3;
  }

  .sizeguide .alt {
    display: none;
  }

  .sizeguide input[type='checkbox']:checked ~ table .alt {
    display: inline;
  }

  .sizeguide input[type='checkbox']:checked ~ table .default {
    display: none;
  }
{% endstyle %}

Then paste this line into the popup’s Custom Liquid block:

{% render 'tshirt-size' %}

The snippet contains the chart, unit switch, and country note. Add the visible heading and any fit advice as separate blocks inside the popup. For example:

Fit tip: Lay a T-shirt you already own flat, measure across the chest, and compare it with the Chest Width above.

Replace the sample measurements with your own. Both units are stored in the markup, so update both values together. This is not an automatic conversion engine or a US-to-EU clothing-size converter.

The unit switch needs no additional JavaScript. The popup still uses Horizon’s existing JavaScript to open and close.

3. Make the size chart country-aware with Liquid

We read localization.country to choose the starting unit automatically. This is Shopify’s current storefront country, whether it comes from the store’s default context or a shopper’s selection. The size chart does not perform its own location detection.

The country list near the top of the snippet sets our preferred inches defaults:

assign imperial_countries = 'US,CA,GB,IE,AU,NZ' | split: ','

This line is already included inside the snippet’s Liquid block; do not paste it separately into Custom Liquid. Despite its variable name, it is our configurable preference list, not a list of official national measurement standards. Change the country codes to suit your store.

Countries in the list start with inches; others start with centimeters. In the screenshots below, the United States starts with inches and Germany starts with centimeters.

United States — inches

Size guide for the United States showing inches as the default unit and chest width and body length measurements.

Germany — centimeters

Size guide for Germany showing centimeters as the default unit and chest width and body length measurements.

The same size chart with different starting units. Select either screenshot to view it at full size.

The checkbox’s initial state comes from Liquid. After that, shoppers can switch units themselves. The Default unit note continues to describe the starting preference, not the current selection. Reloading the page resets the switch to the country default; this version does not save a manual preference.

Adapt it to your products, then test

Products sharing a template will share this fixed chart. Use separate templates or conditional rendering when products need different measurements. Other themes can use the same idea, but their popup and block structure may need adaptation.

If you use an AI coding assistant, give it the snippet and your relevant popup and Custom Liquid files. Ask it to preserve existing customizations and explain its changes. Never include passwords, access tokens, or customer data, and test its output on the duplicate theme.

  • Check country defaults after a page reload, plus manual switching in both directions.
  • Verify every measurement, unit label, and rounded value.
  • Check mobile table width, popup scrolling, and the close control.
  • Test keyboard focus, the unit switch’s accessible name, and returning focus after closing the popup.
  • Keep each switch ID unique if you render more than one chart, and check for conflicting theme CSS.

Once those checks pass, the result is a size guide built into your product page: a native popup, a custom chart, and a useful default that shoppers can override.

Get Shopify help _

Want a size chart like this?

We can build one for your store.

$99 USD

ONE CUSTOM FEATURE · 30-DAY GUARANTEE

Build my size chart