DEV Community

Cover image for How to Debug Shopify Liquid: A Complete Guide
Yakhyo Ismoildjonov
Yakhyo Ismoildjonov

Posted on

How to Debug Shopify Liquid: A Complete Guide

Debugging Shopify Liquid templates is notoriously difficult. There's no built-in debugger, no breakpoints, no step-through execution. When something breaks, you're often left staring at a blank page or cryptic error message with no clear path forward.

This guide covers every method for debugging Liquid — from basic techniques to advanced tooling — so you can diagnose and fix issues faster.


Why Is Liquid Hard to Debug?

Liquid is a templating language, not a programming language. It runs server-side on Shopify's infrastructure, which means:

  • No browser DevTools — You can't inspect Liquid like you inspect JavaScript
  • No console.log — There's no native way to print debug output
  • Silent failures — Many errors render as empty strings instead of error messages
  • No stack traces — When something breaks, you don't know where
  • Server-rendered — Every change requires a page refresh to test

This makes debugging a slow, frustrating process of trial and error.


Method 1: The JSON Filter

The most common debugging technique is outputting objects as JSON:

{{ product | json }}
Enter fullscreen mode Exit fullscreen mode

This renders the entire product object as a JSON string in your HTML. You can then:

  1. View page source or inspect element
  2. Copy the JSON output
  3. Paste into a JSON formatter to read it

Limitations

  • Clutters your HTML output
  • Easy to forget and leave in production code
  • Requires refreshing the page for every change
  • Large objects are hard to navigate
  • No syntax highlighting or search

Better: Wrap in a script tag

<script>
  console.log('Product:', {{ product | json }});
</script>
Enter fullscreen mode Exit fullscreen mode

Now you can view it in browser DevTools console with proper formatting.


Method 2: Shopify Theme Check

Theme Check is Shopify's official linter for Liquid. It catches common errors before you deploy.

Installation

# Via Shopify CLI
shopify theme check

# Or standalone
gem install theme-check
theme-check
Enter fullscreen mode Exit fullscreen mode

What it catches

  • Undefined objects and variables
  • Deprecated tags and filters
  • Missing template files
  • Performance issues (too many API calls)
  • Translation key errors

Limitations

  • Static analysis only — doesn't catch runtime errors
  • Can't inspect actual data values
  • Runs in terminal, not in browser
  • No live debugging

Method 3: Shopify's Built-in Error Messages

Liquid does surface some errors directly in the HTML output. Look for:

Liquid error: undefined method 'title' for nil:NilClass
Enter fullscreen mode Exit fullscreen mode
Liquid syntax error: Unknown tag 'endfor'
Enter fullscreen mode Exit fullscreen mode

How to find them

  1. View page source (Cmd+U / Ctrl+U)
  2. Search for "Liquid error" or "Liquid syntax"
  3. The error message usually indicates the file and line

Common error patterns

Error Cause Fix
undefined method for nil:NilClass Accessing property on null object Add {% if object %} check
Unknown tag Typo in tag name Check spelling (endif not end if)
Could not find snippet Missing snippet file Create the file or fix the path
Invalid JSON Malformed JSON in section schema Validate your JSON syntax

Method 4: Preview Inspector (Theme Editor)

Shopify's theme customizer has a basic inspector:

  1. Open theme customizer
  2. Click on a section
  3. View available settings and blocks

Limitations

  • Only shows section settings, not Liquid objects
  • Can't inspect product, cart, or collection data
  • No expression evaluation
  • No error detection

Method 5: Browser DevTools (for JavaScript)

If your Liquid outputs data for JavaScript consumption, you can debug the JavaScript side:

<script>
  window.productData = {{ product | json }};
</script>
Enter fullscreen mode Exit fullscreen mode

Then in browser console:

console.log(productData.title);
console.log(productData.variants[0].price);
Enter fullscreen mode Exit fullscreen mode

Limitations

  • Only works for data you explicitly expose
  • Can't access Liquid-only objects like template or request
  • Requires modifying your code to expose data

Method 6: In-Browser Liquid DevTools

The most comprehensive solution is using dedicated developer tools that run in the browser.

Shopify Theme Devtools is an open-source panel that provides:

Objects Inspector

Browse all Liquid objects in a collapsible tree view:

  • shop — Store settings, currency, locale
  • product — Current product with variants, images, metafields
  • collection — Collection data with products
  • cart — Live cart state with items and attributes
  • customer — Logged-in customer data
  • template — Current template name and directory
  • request — Page URL, host, path

Click any property to copy its Liquid path.

Live Expression Evaluator

Test Liquid expressions without refreshing:

> product.title
"Classic Cotton T-Shirt"

> product.price | money
"$29.99"

> cart.items | size
3

> product.variants | first | json
{"id": 12345, "title": "Small / Blue", ...}
Enter fullscreen mode Exit fullscreen mode

Supports 50+ Liquid filters including money, money_with_currency, img_url, asset_url, and more.

Automatic Error Detection

Scans the page for common Liquid issues:

Error Type Example
Liquid errors Liquid error: undefined method 'size'
Syntax errors Liquid syntax error: Unknown tag 'endif'
Drop object leaks #<ProductDrop:0x00007f...>
Missing snippets Could not find snippet 'missing-file'
Schema errors Invalid JSON in section schema
JSON filter errors {"error":"not found"}

Each error includes a suggested fix.

Cart Debugging

  • View live cart state with all items and properties
  • Adjust quantities without leaving the panel
  • Save and restore cart snapshots
  • View cart history with timestamps

Installation

npx shopify-theme-devtools init --inject
Enter fullscreen mode Exit fullscreen mode

Then press Cmd+Shift+D (Mac) or Ctrl+Shift+D (Windows) to open.

Only loads on development themes — safe to commit to your repository.


Common Liquid Errors and Solutions

1. "undefined method for nil:NilClass"

Cause: Accessing a property on an object that doesn't exist.

<!-- This breaks if product is nil -->
{{ product.title }}
Enter fullscreen mode Exit fullscreen mode

Fix: Always check if the object exists first.

{% if product %}
  {{ product.title }}
{% endif %}
Enter fullscreen mode Exit fullscreen mode

2. "Unknown tag"

Cause: Typo in a Liquid tag name.

<!-- Wrong -->
{% end if %}

<!-- Correct -->
{% endif %}
Enter fullscreen mode Exit fullscreen mode

3. Drop object leak (#ProductDrop:0x...)

Cause: Outputting a Liquid object without the json filter.

<!-- Wrong — renders as #<ProductDrop:0x...> -->
<script>
  const product = {{ product }};
</script>

<!-- Correct -->
<script>
  const product = {{ product | json }};
</script>
Enter fullscreen mode Exit fullscreen mode

4. "Could not find snippet"

Cause: Rendering a snippet that doesn't exist.

{% render 'non-existent-snippet' %}
Enter fullscreen mode Exit fullscreen mode

Fix: Check the snippet filename and ensure it's in the snippets/ folder.

5. Empty output (no error)

Cause: Variable is nil or empty, but Liquid doesn't error — it just outputs nothing.

Debug: Use the inspect filter or JSON output:

{{ my_variable | json }}
<!-- Shows "null" if nil, actual value otherwise -->
Enter fullscreen mode Exit fullscreen mode

6. "Invalid JSON in schema"

Cause: Section schema has malformed JSON.

{% schema %}
{
  "name": "My Section",
  "settings": [
    {
      "type": "text",
      "id": "title"
      <!-- Missing comma here -->
      "label": "Title"
    }
  ]
}
{% endschema %}
Enter fullscreen mode Exit fullscreen mode

Fix: Validate your JSON at jsonlint.com.

7. Incorrect money formatting

Cause: Using raw price values without the money filter.

<!-- Wrong — outputs "2999" -->
{{ product.price }}

<!-- Correct — outputs "$29.99" -->
{{ product.price | money }}
Enter fullscreen mode Exit fullscreen mode

8. Array index out of bounds

Cause: Accessing an array index that doesn't exist.

<!-- Breaks if product has fewer than 3 images -->
{{ product.images[2].src }}
Enter fullscreen mode Exit fullscreen mode

Fix: Check array size first:

{% if product.images.size > 2 %}
  {{ product.images[2].src }}
{% endif %}
Enter fullscreen mode Exit fullscreen mode

Debugging Workflow: A Step-by-Step Process

When you encounter an issue, follow this process:

Step 1: Check for visible errors

Search your page source for "Liquid error" or "Liquid syntax error".

Step 2: Isolate the problem

Comment out sections of code until the error disappears:

{% comment %}
  {{ potentially_broken_code }}
{% endcomment %}
Enter fullscreen mode Exit fullscreen mode

Step 3: Inspect the data

Use JSON output or a devtools panel to see what data is actually available:

{{ product | json }}
Enter fullscreen mode Exit fullscreen mode

Step 4: Verify object existence

Add existence checks around the problematic code:

{% if product %}
  {% if product.metafields.custom.size > 0 %}
    {{ product.metafields.custom | json }}
  {% else %}
    <!-- No custom metafields -->
  {% endif %}
{% else %}
  <!-- Product is nil -->
{% endif %}
Enter fullscreen mode Exit fullscreen mode

Step 5: Test expressions incrementally

Break complex expressions into smaller parts:

<!-- Instead of this -->
{{ product.metafields.custom.care_instructions.value | newline_to_br }}

<!-- Test each part -->
{{ product.metafields | json }}
{{ product.metafields.custom | json }}
{{ product.metafields.custom.care_instructions | json }}
Enter fullscreen mode Exit fullscreen mode

Performance Debugging

Some Liquid issues aren't errors — they're performance problems.

Too many API calls

Each time you access all_products, collections, or similar global objects, Shopify makes API calls. Too many calls slow down your page.

<!-- Bad — N+1 query problem -->
{% for product_handle in product_handles %}
  {% assign p = all_products[product_handle] %}
  {{ p.title }}
{% endfor %}

<!-- Better — use collection or section settings -->
{% for product in collection.products %}
  {{ product.title }}
{% endfor %}
Enter fullscreen mode Exit fullscreen mode

Heavy JSON output

Outputting large objects as JSON increases page size:

<!-- Bad — includes all product data -->
{{ product | json }}

<!-- Better — only what you need -->
{
  "id": {{ product.id | json }},
  "title": {{ product.title | json }},
  "price": {{ product.price | json }}
}
Enter fullscreen mode Exit fullscreen mode

Identify slow sections

Use browser DevTools Network tab to check page load time. If pages are slow:

  1. Check for excessive for loops
  2. Look for all_products or collections calls
  3. Reduce JSON payload size
  4. Consider lazy loading non-critical content

Debugging Metafields

Metafields are a common source of confusion because they may or may not exist.

Check if a metafield exists

{% if product.metafields.custom.care_instructions %}
  {{ product.metafields.custom.care_instructions.value }}
{% else %}
  No care instructions available.
{% endif %}
Enter fullscreen mode Exit fullscreen mode

List all metafields

<pre>{{ product.metafields | json }}</pre>
Enter fullscreen mode Exit fullscreen mode

Access nested metafield values

For JSON metafields:

{% assign data = product.metafields.custom.specs.value %}
{{ data.weight }}
{{ data.dimensions }}
Enter fullscreen mode Exit fullscreen mode

Summary

Method Best for Limitations
`\ json` filter Quick data inspection
Theme Check Pre-deploy linting Static only, no runtime
Browser DevTools JavaScript debugging Can't access Liquid objects
Page source search Finding error messages No object inspection
Shopify Theme Devtools Full debugging workflow Requires installation

For most developers, combining Theme Check (for linting) with an in-browser devtools panel (for runtime debugging) provides the most complete debugging experience.


Additional Resources


What debugging techniques do you use for Shopify Liquid? Share your tips in the comments.


Tags: #shopify #liquid #debugging #webdev #ecommerce #tutorial #devtools

Top comments (0)