Skip to Content
DocsCustom Liquid

Custom Liquid

When a Mercer section doesn’t fit your needs, the Custom Liquid section and the Custom Liquid block let you drop in arbitrary Liquid, HTML, and inline style markup. This guide shows where each lives, when to use which, and what’s safe (and unsafe) to put inside.

Mercer ships two Custom Liquid surfaces:

  • Custom Liquid section — a free-form section you can add anywhere a section is allowed (every template except gift card and password).
  • Custom Liquid block — available inside every section that supports @app blocks. Use this when you want to inline custom markup inside an existing section instead of as its own row on the page.

If you’re new to Liquid, see Shopify’s Liquid reference .

Custom Liquid section

The section has one setting: a Custom Liquid textarea. Whatever you put in it is rendered as-is — Liquid evaluates, HTML renders, inline style and script tags work.

To add it:

  1. Open the Theme Editor.
  2. Pick the template you want to add it to.
  3. Click Add sectionCustom Liquid.
  4. Click into the section, paste your Liquid / HTML.
  5. Save.

Example: announcement strip

<div style="background: #FFD7BA; color: #4A1F00; text-align: center; padding: 0.5rem;"> Free shipping on orders over $80 — code <strong>SUMMER</strong>. </div>

Example: time-gated banner (Liquid if + now)

{%- assign launch = '2026-06-01' | date: '%s' -%} {%- assign now = 'now' | date: '%s' -%} {%- if now < launch -%} <div style="background: #1A1A1A; color: #fff; text-align: center; padding: 1rem;"> The Spring 2026 collection drops June 1. </div> {%- endif -%}

Example: pulling a metafield value

{%- assign tagline = shop.metafields.brand.tagline -%} {%- if tagline -%} <p class="brand-tagline">{{ tagline }}</p> {%- endif -%}

Example: third-party embed

<!-- Press testimonial widget --> <div id="press-widget" data-widget="press"></div> <script src="https://example.com/widget.js" defer></script>

Custom Liquid block

Available inside any section that has a “Blocks” panel and supports @app blocks. To add:

  1. Open a section in the Editor (e.g. Image with text).
  2. Scroll the section’s settings panel to Blocks at the bottom.
  3. Click Add blockCustom Liquid.
  4. Drag to reorder among the section’s other blocks.
  5. Click into the block, paste your Liquid / HTML.

The block lets you compose custom content inside an existing section without breaking the section’s layout. Common pattern: appending a note below an image-with-text block, or inserting a custom “Why we built this” paragraph between two columns of a multi-column section.

When to use which

If you want…Use the…
A whole-row, full-width custom sliceCustom Liquid section
Custom markup inside an existing section’s flowCustom Liquid block
To embed a third-party app without codeThe third-party app’s app block
To show different content per market / localeA Custom Liquid section with if request.locale.iso_code == 'en'
To override Mercer’s PDP layoutEdit the main-product template in the Editor; don’t fight it with Custom Liquid

Available Liquid drops and filters

Inside Custom Liquid, you have access to all of Shopify’s standard global drops:

  • shop — store name, currency, etc.
  • request — the current request (request.locale, request.country).
  • customer — the signed-in customer (or nil).
  • cart — the current cart.
  • linklists.<handle> — your menu lists.
  • routes — Shopify route helpers (routes.cart_url, etc.).
  • localization — the active country / language.
  • template — the current template name.
  • page_title, page_description — current page meta.

Plus Mercer-defined helpers via the Mercer object:

  • Mercer.routes — locale-aware route prefixes for AJAX calls.

Localization in Custom Liquid

If you hard-code a path like /products/wool-trench, that path will not be auto-localized for visitors in other markets. To localize correctly, use routes or the localized-href snippet:

<!-- Bad: hard-coded path doesn't localize --> <a href="/products/wool-trench">Shop the trench</a> <!-- Good: routes-prefixed --> <a href="{{ routes.collections_url }}/outerwear">Shop outerwear</a> <!-- Best: explicit collection drop --> {%- assign coll = collections.outerwear -%} {%- if coll -%} <a href="{{ coll.url }}">{{ coll.title }}</a> {%- endif -%}

For internal links to products / collections / pages, prefer the Shopify drops (product.url, collection.url, page.url) — they auto-localize via request.locale_root.

Custom CSS

Inline style tags work inside Custom Liquid. For one-off styling, this is fine. For anything cross-page or theme-wide, you’re better off asking Mercer Studio to add a setting that exposes the value you need (via support ) — Custom Liquid CSS isn’t easily reusable.

<style> .my-custom-banner { background: var(--surface-alt); color: var(--ink); padding: var(--space-3); } </style> <div class="my-custom-banner"> Custom announcement using Mercer's design tokens. </div>

Mercer’s design tokens (the var(--ink), var(--surface), var(--space-3) etc. above) are available globally. Using them keeps your custom block visually consistent with the rest of the storefront.

Custom JavaScript

Inline script tags work, but with caveats:

  • Scripts run after the section’s HTML is in the DOM.
  • Scripts loaded via a script tag with a src attribute should use defer to avoid blocking render.
  • Mercer’s own JS is loaded with defer — your scripts may run before or after Mercer’s scripts depending on order. Don’t rely on Mercer-internal globals (Mercer.*) being available at script execution time; wait for DOMContentLoaded if needed.
<script defer> document.addEventListener('DOMContentLoaded', () => { // your code }); </script>

Security and what NOT to put in Custom Liquid

Custom Liquid runs as the merchant’s code. It’s not sandboxed. Some things to avoid:

  • Don’t paste customer-submitted content without filtering. Shopify form submissions (cart notes, customer names, etc.) can contain HTML; rendering them raw is an XSS vector. If you absolutely must render them, append | escape: {{ form.name | escape }} not {{ form.name }}.
  • Don’t paste credentials. Custom Liquid renders to public HTML. API keys, tokens, passwords are leaked to anyone who views the page source.
  • Don’t disable Mercer’s script defers. Mercer’s perf budget depends on all main-bundle scripts being deferred. If your custom script blocks render, your LCP and CLS metrics suffer.

If a third-party widget you want to embed asks you to inject a script tag without defer, ask the vendor for a deferred build. If they don’t have one, that’s a perf cost you’re choosing to pay; it won’t fall on Mercer.

Editor preview vs production rendering

The Editor’s preview pane re-renders Custom Liquid on every save. Some Liquid behaviors differ between Editor and live storefront:

  • customer is always nil inside the Editor (you’re not logged in as a customer when previewing as a merchant).
  • request.country defaults to your shop’s primary country in Editor preview; on production, it reflects the visitor’s actual geo-IP.
  • cart is empty in the Editor.

If you build a Custom Liquid block that’s customer-aware or cart-aware, test it on the live storefront with a real customer account.

Common Custom Liquid pitfalls

”My Custom Liquid breaks the page”

A syntax error in Liquid can break the entire page render. Check the storefront’s debug HTML comments for the Liquid error: ... line; that tells you which line of your Liquid failed.

If the page won’t render at all, save an empty Custom Liquid first to restore the section, then debug your snippet in a smaller scope.

”My script runs twice”

Most likely you’ve added a script tag to a Custom Liquid block inside a section, and that section appears more than once on the page. Each section instance renders its own copy of the block. Solutions:

  • Wrap the script in a “has it run yet” guard: if (window.__myWidget) return; window.__myWidget = true;
  • Move the script to a Custom Liquid section instead of a block, and add it to the page once.

”My styles don’t apply”

Inline style tags work, but specificity issues can mean Mercer’s own CSS overrides yours. Use the Mercer design tokens (var(--ink), var(--space-3)) to compose with the theme; or scope your selectors with a unique class (e.g. .my-banner-XYZ) and avoid using !important.

”My CTA button doesn’t look like Mercer’s other buttons”

Use Mercer’s button class:

<a class="btn" href="...">My CTA</a> <a class="btn btn--outline" href="...">Outlined CTA</a> <a class="btn btn--link" href="...">Link-style CTA</a>

The button styles inherit your preset’s radius / border / letter-spacing settings. Hand-coded buttons won’t.

What’s next

  • Read Section reference to see if a built-in section can replace your Custom Liquid use case.
  • Read the FAQ for general theme gotchas.
  • For widgets / sections you’d like to see built into Mercer natively, email feedback@mercertheme.com.