← Back to guides
ExperienceLiquid BasicsLiquid · Published 2026-06-16 · 11 min read

Reusable Shopify Snippets: Agency Workflows That Scale

How we organize snippets/, naming conventions, render parameters, and shared logic libraries across client themes — so sections stay thin and rescue projects do not drown in copy-paste Liquid.

Share with Shopify developers — useful guides spread faster in theme dev communities.

The third rescue project with five copies of the same product card snippet convinced K2 Devworks to standardize snippet libraries. Snippets are not glamorous — but duplicate {% render %} paths with divergent markup are how agencies lose margin on every subsequent template change.

Sections get the glory — heroes, lookbooks, PDP bands — but snippets are where agency quality compounds or collapses. A healthy snippets/ folder means new sections ship in hours because card-product, icon, price, and badge logic already exist. An unhealthy one means every developer pastes slightly different price markup until compare-at display breaks on collection pages but works on search. K2 Devworks formalized snippet workflows in 2022 after auditing a wholesale client with eleven variations of vendor display logic. The system below covers when to extract, how to name, how to pass parameters with render, and how starter packs stay synchronized across client repos. See Liquid snippets hub for copy-ready patterns.

Snippets versus sections: division of labor

Sections are merchant-editable modules with {% schema %} registered on JSON templates. Snippets are developer-controlled partials without schema — called via {% render %}. Merchants do not add snippets from the theme editor; they edit sections that call snippets. If a merchant needs to change icon labels, expose settings on the section and pass values into the snippet. If developers need shared math for sale badges, hide it in snippets. Blurring this boundary — stuffing schema into snippets via workarounds — creates support nightmares. Read How to Create Reusable Sections for section side; this article owns snippet side.

Starter snippet pack we copy into new clients

Every new theme repo gets a baseline pack before custom sections land: icon.liquid (SVG sprite or inline by name param), price.liquid (product or variant price with compare-at), card-product.liquid (collection tile), card-article.liquid (blog tile), loading-spinner.liquid, pagination.liquid, and meta-tags.liquid helpers where needed. Optional B2B pack adds card-product-b2b with volume hints. We tag the pack version in a comment at top of each file — Snippet pack v2.4 — so diffing across client forks is possible. Updates to the starter pack do not auto-merge to old clients; we cherry-pick when fixing security or platform deprecations.

{%- comment -%} snippets/icon.liquid — pack v2.4 {%- endcomment -%}
{%- liquid
  assign icon_name = name | default: 'placeholder'
  assign css_class = class | default: 'icon'
-%}

render parameters done explicitly

render requires explicit parameter passing — that is a feature. {% render 'card-product', product: product, show_vendor: section.settings.show_vendor, lazy_load: true %} documents the contract at the call site. We ban implicit reliance on parent scope variables left over from include migrations. Code review grep for {% include %} hits zero before merge. Liquid mistakes we still see covers include fallout; Liquid for Beginners teaches render syntax for juniors.

{%- comment -%} Section loop — explicit render {%- endcomment -%}
{% for product in collection.products limit: section.settings.limit %}
  {% render 'card-product',
    product: product,
    show_vendor: section.settings.show_vendor,
    image_ratio: section.settings.image_ratio,
    lazy_load: forloop.index > 2
  %}
{% endfor %}

Naming conventions that survive handoffs

Snippet filenames are kebab-case, descriptive, prefixed by domain when helpful: card-product not productCard; price-formatted not price2. Icon snippets use icon- prefix only when multiple icon systems coexist — icon-social.liquid versus icon-ui.liquid. Avoid client brand prefixes unless two conflicting card-product implementations must coexist temporarily during migration — card-product-legacy.liquid with sunset date in comment. Consistency matters more than cleverness; freelancers should find card-product without reading Slack history.

Price and money snippets

Price display is the highest-risk snippet because sales and legal care about correctness. One price.liquid accepts product or variant, outputs compare-at and sale states, respects money filters, optional B2B hide-prices flag. Sections never duplicate {% if product.compare_at_price > product.price %} blocks. When markets and currency conversion enter scope, centralizing in price.liquid prevents collection-page versus PDP mismatches. Test with zero-price variants, sold out, and compare-at equal to price edge cases. Liquid cheat sheet money filters section is required reading before editing price.liquid.

{%- comment -%} snippets/price.liquid {%- endcomment -%}
{%- liquid
  assign target = variant | default: product.selected_or_first_available_variant
-%}
{% if target.compare_at_price > target.price %} {{ target.compare_at_price | money }} {{ target.price | money }} {% else %} {{ target.price | money }} {% endif %}

Product card snippet architecture

card-product.liquid is the most reused snippet in agency work. Parameters we standardize: product, show_vendor, show_rating, image_ratio, lazy_load, and optional collection context for swatches. Secondary image on hover is a boolean — disabled on mobile-first clients. Swatch integration reads theme settings or metafields through passed flags, not global hacks. When Dawn's card-product differs materially, we wrap Dawn's markup in a snippet named card-product-dawn for fork themes, not mash two paradigms in one file with endless if theme.name branches — that does not work; use separate snippets per base theme when necessary.

Extracting from sections: the refactor trigger

We extract snippets when the second section copies paste, or when a section passes 200 lines. Refactor steps: identify pure markup chunk, move to snippets/, replace with render call, pass only needed variables, test all calling sections on duplicate theme, delete dead code. Extract metafield access for badges into snippet badge-metafield.liquid when three sections read custom.badges. Document extraction in PR so future developers know card-product is canonical. Debugging production themes reminds us to grep all render call sites after signature changes.

Documentation without a separate wiki

Snippets lack schema self-documentation. We use a snippets/README comment block in repo — not always committed as README.md per client policy — listing each snippet, parameters, and example render call. Minimum: one line header comment in every snippet file describing params. card-product.liquid: Params: product (required), show_vendor (bool), lazy_load (bool). Junior developers search snippets/ before writing new loops. For complex snippets, link to Loops guide in comment footer.

SVG and icon workflow

Figma exports SVGs with chaotic filenames. We normalize into icon.liquid case statement or separate assets/*.svg loaded via asset_url when icons are large. UI icons use currentColor for theme color_scheme compatibility. Social icons may be image_picker settings on footer sections passing URLs into render — merchant replaces LinkedIn icon without deploy. Accessibility: decorative icons aria-hidden="true"; functional icons get title and aria-label from passed params.

Snippets and performance

render adds clarity, not magic performance cost — but snippet explosion inside tight loops matters. card-product inside {% for product in collection.products %} without limit still kills TTFB. Snippets should not hide unbounded loops; callers enforce limits. Avoid nested render chains five deep in hot paths — flatten when profiling shows Liquid render time spiking. Theme performance tips applies at call site, not only inside snippet files.

Anti-patterns we reject in code review

  • {% include %} — automatic fail; migrate to render.
  • Snippets reading global section.settings without passed params — implicit coupling.
  • God snippet product-all-info.liquid rendering entire PDP — unmaintainable.
  • Copy-paste card markup with one class renamed — extract instead.
  • Metafield namespace hardcoded in six snippets — centralize namespace assign in one helper snippet.

Cross-client maintenance reality

Snippets are per-theme Git repos — not a shared package. When we fix a price display bug in the starter pack, we notify retainer clients and cherry-pick. For active retainers, snippet pack version is in project README. Agencies pretending one snippet library syncs magically across forty clients learn painful truths during Shopify platform deprecations — plan manual propagation. The workflow still beats ad hoc copy-paste because fixes are copy-pasteable as whole files with clear diffs.

Onboarding developers to snippet standards

Day one on client theme: read snippets/ inventory, render card-product on a test section, run Theme Check, fix one include if rescue repo. Day two: extract duplicate markup from assigned section. Dhruv pairs juniors with snippet review before first solo section merge. Standards live in code review comments referencing this article and cheat sheet — not buried PDFs.

Filter, sort, and pagination snippets

Collection filtering on OS 2.0 often uses Search & Discovery or apps, but custom themes still ship snippets/facets.liquid, snippets/pagination.liquid, and snippets/sort-by.liquid. These interact with collection.url and filter parameters — easy to break with wrong form actions. We keep pagination logic in one snippet accepting paginate object and anchor param. Facet snippets read filter objects passed from section — not global hacks. When porting legacy themes, facet markup is high-risk; test filtered URLs in staging before launch.

Internationalization and market-aware snippets

Markets and multi-currency complicate price.liquid and card-product.liquid. Snippets should use money filters and let Shopify handle conversion display — avoid hardcoded currency symbols. For market-specific badges — ships-from-EU — pass booleans from sections reading localization or metafields. Do not branch on request.host in snippets without documentation; markets API patterns are cleaner on Plus. Test snippets with at least two currencies and one translated locale before client delivery.

Snippet harness testing without a test runner

Shopify themes lack Jest for Liquid. We use fixture sections — sections/snippet-test-harness.liquid hidden from presets — that render a snippet with mock parameters and edge-case products on a draft template only developers access. QA loads the harness page on duplicate theme, visually confirms price states and card variants. Low-tech but effective. Delete harness before merchant handoff or hide template from navigation.

Metafield helper snippets

Repeated metafield access patterns belong in snippets/metafield-badge.liquid or similar — pass namespace, key, and product. Centralizing prevents namespace drift when merchandising renames metafield definitions. Document required metafield definitions in theme README. When metafields are empty, snippets return empty string without breaking layout — callers wrap in {% if %} when needed. Metafields tutorial pairs with snippet helpers for client stores heavy on custom attributes.

Legacy include migration playbook

Rescue themes with forty include calls migrate incrementally: grep include, list snippets, convert to render with explicit params one file per PR, test all call sites. Snippets that relied on leaked parent variables need refactor — assign variables in parent before render. Migration sprint dedicates two days only to include eradication before new feature work. Theme Check deprecated tag warnings become CI failures after migration completes.

Snippet pack release notes

When starter pack updates — price.liquid compare-at fix, icon.liquid new social icons — we publish internal release notes: affected snippets, breaking parameter changes, cherry-pick instructions for retainers. Version comment in file header increments. Treat snippet pack like a micro internal library even without npm packaging. Discipline here prevented a Black Friday incident when compare-at logic fix needed to propagate to eight active client themes in forty-eight hours.

Snippets with JavaScript companions

Some snippets pair with theme JS — card-product with quick-add buttons, facets with AJAX collection updates. Keep data attributes in snippet markup stable; JS reads data-product-id and data-variant-id from snippet output. When refactoring snippet HTML, grep assets/*.js for selectors. Breaking snippet markup without updating JS causes silent failures — buttons that do nothing. Co-locate comment in snippet and JS file referencing each other.

Agency code review snippet checklist

Reviewers verify: render not include, explicit params, no unbounded loops, money and image_url filters present, empty state handled, comment header documents params, no client-specific hardcoded handles. Snippet PRs faster to review than section PRs when standards are enforced — smaller diff, clearer contract. Reject PRs that add fourth near-duplicate card variant; require extending card-product with params instead.

When not to snippet

Over-snippetting hurts readability. One-off markup used in a single section stays in the section file. Snippet extraction threshold is second use, not hypothetical reuse. Premature abstraction scatters logic — developers grep six files to understand one card. Reusable sections covers section-level reuse; snippets are finer-grained. Balance thin sections with grep-friendly snippet count — we aim for fifteen to twenty-five snippets on mature client themes, not eighty.

Snippets are also where production debugging pays off: one fix to price.liquid updates every collection grid on the store. When rescue projects have divergent price markup per template, snippet unification is week one — before any new feature work. The ROI argument wins client approval for refactor sprints that feel invisible but prevent recurring bugs.

Sections are what merchants touch. Snippets are what keep your agency from re-solving the same Liquid puzzle on every project.

Build your snippet pack this week

Audit your active client theme: grep for compare_at_price, count duplicate card markup blocks, list all {% include %} hits for migration. Create icon.liquid and price.liquid if missing. Extract one duplicated chunk into card-product.liquid and update two sections to render it. Document parameters in file headers. Snippet discipline is boring until rescue projects become rare — then it is the highest ROI process on your theme team.

Schedule quarterly snippet pack reviews on retainer clients — thirty minutes to diff starter pack version against client snippets/ for drift. Cherry-pick security and pricing fixes proactively. Merchants never notice snippet maintenance; they notice when prices display wrong on Black Friday and you fix eight stores in one afternoon because snippets were standardized.

Start with card-product.liquid and price.liquid on your next retainer — even if the theme already has them under different names. Rename and consolidate once, document render params, and every future section ships faster. Snippet debt compounds silently until a rescue audit prices forty hours to unify; prevention costs an afternoon. Snippet standards are the quiet competitive advantage agencies underestimate until rescue work finally disappears. Invest one afternoon per retainer; compound returns for years.

Frequently asked questions

When should logic move from a section to a snippet?

When the same markup or logic appears in two or more sections, or when a section file exceeds roughly 200 lines with reusable chunks — product cards, icons, price formatting, pagination. Snippets keep sections focused on layout and section.settings.

include or render — which do agencies use?

Always render. include is deprecated, leaks parent scope, and makes debugging harder. render passes variables explicitly and is the only pattern we allow in code review.

How do we version snippets across multiple client themes?

We maintain an internal starter snippet pack copied into new projects, then fork per client. Snippets are not shared across stores automatically — document which starter version a theme inherited.

Can snippets accept block objects from section loops?

Yes. Pass block: block or specific fields block.settings.image into render calls. Do not rely on implicit scope from include-era patterns.

Where do SVG icons belong — snippets or assets?

Inline SVG for small icons controlled by CSS currentColor in snippets/icon.liquid; larger brand assets in assets/ referenced by image_url when merchants need replacement via settings.

Topic cluster

Liquid Basics

Objects, tags, filters, loops, and beginner Liquid workflows.

Convert HTML to Shopify Liquid

Paste HTML & generate Liquid with schema, blocks, and scoped CSS. No signup required.

Share

Share this guide

Found this guide useful? Share it with other Shopify developers on LinkedIn, X, or Reddit.

Authors

About the authors

Practical Shopify section workflows from the developers who build and maintain this tool.

Dhruv Goyani, Shopify Developer at HTML to Liquid Converter

Dhruv Goyani

3 years web design + 3 years Shopify development experience

Dhruv combines web design and Shopify theme development — converting Figma and static HTML into merchant-editable OS 2.0 sections for client stores. He focuses on schema structure, section presets, and clean handoffs between design and Liquid.

Follow Dhruv on LinkedIn
Nishad Kikani, Lead Shopify Developer at HTML to Liquid Converter

Nishad Kikani

2 years web design + 6 years Shopify development experience

Nishad has six years of Shopify theme engineering — Dawn migrations, JSON templates, performance tuning, and complex block-based sections. He leads client delivery, code review, and the production standards behind every export from HTML to Liquid Converter.

Follow Nishad on LinkedIn

Meet our Shopify developers · Our development experience

Editorial review

Reviewed by the HTML to Liquid Converter team

Dhruv Goyani, Shopify Developer at HTML to Liquid Converter

Dhruv Goyani

3 years web design + 3 years Shopify development experience

LinkedIn profile →
Nishad Kikani, Lead Shopify Developer at HTML to Liquid Converter

Nishad Kikani

2 years web design + 6 years Shopify development experience

LinkedIn profile →

Content is reviewed by the HTML to Liquid Converter Shopify development team before publication. Technical accuracy is validated against current Shopify Online Store 2.0 conventions and active client theme work.

Last updated:

Questions or corrections? Contact us.