Liquid objects are the variables Shopify exposes to your theme. They hold everything from the current product to the store's currency to loop metadata. Knowing which objects exist, what data they carry, and — crucially — where they're available is the foundation of theme development.
This guide is a practical reference to the objects you'll use every day. For copy-paste snippets and a live playground, pair it with the Liquid cheatsheet; when you're ready to build, the HTML to Liquid converter wires these objects into your sections automatically.
How objects work
You output an object's value with double braces and drill into properties with dots:
{{ product.title }}
{{ product.featured_image.alt }}
{{ cart.item_count }}
Objects can represent a single value, a collection of properties, or an array you can loop over. Filters transform their output:
{{ product.price | money }}
{{ product.title | upcase }}
Global objects (available almost everywhere)
These are accessible on most templates without being passed in.
shop
Store-wide information — ideal for headers, footers, and meta tags.
{{ shop.name }}
{{ shop.currency }}
{{ shop.email }}
{{ shop.url }}
request
Context about the current request.
{{ request.page_type }} {# e.g. "product", "collection", "index" #}
{{ request.path }}
{{ request.host }}
{{ request.locale.iso_code }}
{{ request.design_mode }} {# true inside the theme editor #}
request.design_mode is especially useful for disabling autoplay or analytics while a merchant is editing.
routes
Locale- and market-safe URL helpers. Never hard-code paths like /cart — use these:
<a href="{{ routes.root_url }}">Home</a>
<a href="{{ routes.cart_url }}">Cart</a>
<a href="{{ routes.account_url }}">Account</a>
<a href="{{ routes.search_url }}">Search</a>
settings
Global theme settings from config/settings_schema.json.
:root { --brand: {{ settings.colors_primary }}; }
cart, customer, localization
{{ cart.item_count }} items — {{ cart.total_price | money }}
{% if customer %}Hi, {{ customer.first_name }}{% endif %}
{{ localization.country.name }} ({{ localization.country.currency.iso_code }})
Remember: customer is nil when no one is logged in, so always gate it with {% if customer %}.
Resource objects
These represent store resources. Some are global on their own template (e.g. product on a product page); others you reach through a parent.
product
<h1>{{ product.title }}</h1>
<p>{{ product.vendor }} · {{ product.type }}</p>
<p>{{ product.price | money }}</p>
{% if product.compare_at_price > product.price %}
<s>{{ product.compare_at_price | money }}</s>
{% endif %}
<a href="{{ product.url }}">View</a>
Key properties: title, price, compare_at_price, available, vendor, type, tags, handle, url, description, featured_image, images, media, variants, options_with_values, selected_or_first_available_variant, metafields.
variant
{% assign variant = product.selected_or_first_available_variant %}
{{ variant.title }} — {{ variant.price | money }}
SKU: {{ variant.sku }}
Available: {{ variant.available }}
collection
<h1>{{ collection.title }}</h1>
<p>{{ collection.products_count }} products</p>
{% for product in collection.products %}
{{ product.title }}
{% endfor %}
collection.products returns up to 50 products per page — wrap it in {% paginate %} for larger collections.
cart and line_item
{% for item in cart.items %}
{{ item.product.title }} — {{ item.quantity }} × {{ item.price | money }}
{% endfor %}
Content objects: blog, article, page
{{ article.title }}
{{ article.author }}
{{ article.published_at | date: "%B %d, %Y" }}
{{ article.content }}
metafields and metaobject
Custom data attached to a resource. Always read the typed value with .value:
{{ product.metafields.custom.subtitle.value }}
{% assign designer = product.metafields.custom.designer.value %}
{{ designer.name.value }}
You can also access metaobjects directly by type and handle:
{{ metaobjects.testimonials.homepage.title.value }}
The forloop object
Inside a for loop, Shopify gives you a forloop object with loop metadata:
{% for product in collection.products %}
{{ forloop.index }} {# 1-based position #}
{{ forloop.index0 }} {# 0-based position #}
{{ forloop.first }} {# true on first iteration #}
{{ forloop.last }} {# true on last iteration #}
{{ forloop.length }} {# total iterations #}
{% endfor %}
This is how you add "first"/"last" classes, alternate rows, or close a wrapper after the final item. There's a matching tablerowloop object inside {% tablerow %}.
Where objects are available (scope)
Not every object exists on every template — this trips up beginners constantly.
productis global on product templates; elsewhere you reach a product through a parent (collection.products,cart.items[i].product, aproductsetting).collectionis global on collection templates.article/blogare global on article/blog templates.sectionandsection.settingsexist inside a section;blockandblock.settingsexist inside a block loop.cart,shop,request,routes,settings,customer,localizationare effectively global.
If an object is nil where you expected data, the first thing to check is whether you're on the right template — or whether you need to pass it explicitly into a snippet with {% render %}.
Nil-safety and common mistakes
- Guard optional objects:
{% if customer %}…{% endif %},{% if product.featured_image %}…{% endif %}. - Use
defaultfor fallbacks:{{ product.vendor | default: "Unknown" }}. - Read metafields with
.value— outputting the metafield object directly is the legacy behavior;.valueis the documented, type-aware way. - Don't hard-code URLs — use
routesandproduct.url/collection.urlso links stay correct across locales and markets. - Prices are in cents — always pipe through
money, never printcart.total_priceraw. - Snippets have isolated scope —
{% render %}does not inherit parent variables; pass what you need explicitly.
Put objects to work
The fastest way to see objects in action is the Liquid cheatsheet, which renders each one against mock Shopify data in a live playground. When you build a section, the HTML to Liquid converter maps your content onto these objects and settings for you. And to make that content editable, see our guide on converting HTML into a Shopify section and the section schema reference.
Conclusion
Objects are the data layer of every Shopify theme. Learn the global ones (shop, request, routes, settings, cart, customer), the resource ones (product, variant, collection, article), and the loop helpers (forloop), keep scope and nil-safety in mind, and you can read and render any store data with confidence.
Next: browse the full cheatsheet, generate a section schema, or convert your first block of HTML with the free tool.



