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
@appblocks. 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:
- Open the Theme Editor.
- Pick the template you want to add it to.
- Click Add section → Custom Liquid.
- Click into the section, paste your Liquid / HTML.
- 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:
- Open a section in the Editor (e.g. Image with text).
- Scroll the section’s settings panel to Blocks at the bottom.
- Click Add block → Custom Liquid.
- Drag to reorder among the section’s other blocks.
- 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 slice | Custom Liquid section |
| Custom markup inside an existing section’s flow | Custom Liquid block |
| To embed a third-party app without code | The third-party app’s app block |
| To show different content per market / locale | A Custom Liquid section with if request.locale.iso_code == 'en' |
| To override Mercer’s PDP layout | Edit 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 (ornil).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
scripttag with asrcattribute should usedeferto 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 forDOMContentLoadedif 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
scriptdefers. 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:
customeris always nil inside the Editor (you’re not logged in as a customer when previewing as a merchant).request.countrydefaults to your shop’s primary country in Editor preview; on production, it reflects the visitor’s actual geo-IP.cartis 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.