Debug Liquid with the json filter

See what a Liquid object contains: {{ product | json }} in the console or a <pre> block, only in the theme editor, plus the safe way to pass data to JS.

Syntax
{{ object | json }}
Limit to
{% if request.design_mode %}
Excludes
Variant inventory_quantity and inventory_policy
Plan
Every plan
Last checked

In short

Liquid has no debugger, but the json filter comes close: {{ product | json }} prints the whole object as JSON, which you can log to the browser console or show in a <pre> block. Wrap the output in {% if request.design_mode %} so it only appears in the theme editor. The same filter is the safe way to hand Liquid data to JavaScript, because it adds quotes and escapes them for you.

How to use it

  1. In the template or section you’re debugging, add <script>console.log({{ product | json }});</script> inside {% if request.design_mode %}.
  2. Open the page in the theme editor with the browser console open and expand the logged object.
  3. For values on the page itself, print {{ cart | json | escape }} inside a <pre> block.
  4. Remove the debug code when you’re done, and keep production data hand-offs in a <script type="application/json"> tag.

Code

debug.liquid
{%- comment -%}
  Dumps Liquid objects so you can see exactly what a template receives.
  Wrapped in request.design_mode so it only renders inside the theme editor;
  remove it when you're done. The json filter adds the quotes itself, so
  don't wrap the output in quotes.
{%- endcomment -%}
{%- if request.design_mode -%}
  <script>
    console.log('product', {{ product | json }});
    console.log('variant', {{ product.selected_or_first_available_variant | json }});
    console.log('template', {{ template.name | json }}, {{ template.suffix | json }}, 'page_type', {{ request.page_type | json }});
  </script>
{%- endif -%}

{%- comment -%} Or read it on the page in a <pre> block {%- endcomment -%}
{%- if request.design_mode -%}
  <pre style="white-space: pre-wrap">{{ cart | json | escape }}</pre>
{%- endif -%}
pass-data-to-js.liquid
{%- comment -%}
  The same filter in production: hand Liquid data to JavaScript through a
  JSON script tag instead of building JS strings by hand. json escapes quotes,
  so product titles with " or ' can't break the script.
{%- endcomment -%}
<script type="application/json" id="ProductData-{{ product.id }}">
  {
    "id": {{ product.id | json }},
    "title": {{ product.title | json }},
    "variants": {{ product.variants | map: 'id' | json }}
  }
</script>
<script>
  const productData = JSON.parse(document.getElementById('ProductData-{{ product.id }}').textContent);
</script>

Written by Lintel. MIT license: free to use in your own store and in client work.

Limits and edge cases

  • Don’t wrap the output in quotes: the json filter adds them, and extra quotes turn the object into a string.
  • On stores created after December 5, 2017, product JSON leaves out variant inventory_quantity and inventory_policy; read them from individual variants if you need them.
  • Debug output outside design_mode is public: anyone can read it in the page source.
  • request.design_mode shouldn’t change what customers see; use it for editor-only output like this, not for features.

Questions

How do I see what is inside a Liquid object?
Output it with the json filter, {{ product | json }}, and log it to the console or print it in a <pre> block.
Why is inventory_quantity missing from {{ product | json }}?
Shopify removes it (and inventory_policy) from product JSON on stores created after December 5, 2017. Read variant.inventory_quantity directly.
How do I pass Liquid data to JavaScript safely?
Put {{ value | json }} in a <script type="application/json"> tag and JSON.parse it, or assign it directly in a script without extra quotes.
  • Checked on a Shopify store on the date shown. Shopify changes its admin often; if a step looks different, the idea usually still works.
  • Examples use placeholder IDs and your-store.myshopify.com. Replace them with your own.
  • MIT license for the code snippets.

Need this built, tested and maintained for your store? See Shopify development.

Have something to build? Let’s talk it through.

Taking a limited number of projects at a time. Every brief is read by an engineer, not a salesperson.

Gencer KarakayaShopify Engineer

An engineer reads your brief, and we reply by email.