Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.launchmystore.io/llms.txt

Use this file to discover all available pages before exploring further.

Metafields in Aqua / Liquid

Every owner that supports metafields exposes a metafields drop on its Aqua/Liquid object. Access follows the standard {owner}.metafields.{namespace}.{key} pattern, so theme code that reads metafields stays portable. For the full data model (types, owners, validations, REST API), see Metafields Overview.

The basic pattern

{{ product.metafields.custom.badge }}                  {# scalar value, type-aware toString #}
{{ product.metafields.custom.warranty_years }}         {# 5 #}
{{ product.metafields.custom.warranty_years.value }}   {# 5 (decoded) #}
{{ product.metafields.custom.warranty_years.type }}    {# "number_integer" #}
{{ product.metafields.custom.does_not_exist }}         {# (empty, no error) #}
{{ … }} triggers toString() on the metafield drop, which renders type-aware (see render rules below). .value returns the decoded value (number, array, object, …). .type returns the type string. Missing namespaces and missing keys return an empty drop{{ … }} prints empty string, {% if … %} is falsy, no exception is thrown. This makes it safe to reference fields that may not exist on every resource.

Owners

OwnerDrop
Account / storeshop.metafields
Productproduct.metafields
Variantvariant.metafields
Collectioncollection.metafields
Customercustomer.metafields
Orderorder.metafields
Pagepage.metafields
Blogblog.metafields
Articlearticle.metafields

Render rules per type

{{ metafield }} (without .value) calls a type-aware toString:
Type{{ mf }} renders{{ mf.value }} returns
single_line_text_field / multi_line_text_fieldstringstring
rich_text_field (alias rich_text)raw HTML, unescapedraw HTML string
number_integerintegernumber
number_decimaldecimalnumber
boolean"true" or "false"bool
color"#RRGGBB"string
date / date_timeISO stringstring
urlURL stringstring
weight / dimension / volume"<value> <unit>"{ unit, value }
money{amount, currency_code} (use | money filter)object
rating{value, scale_min, scale_max}object
file_referenceURL stringURL string
*_reference (other)id stringid string (or resolved drop, if resolver wired)
list.*iterable array of value-dropsarray
json / json_stringstringified JSONparsed value

Examples

Text and numbers

{% if product.metafields.custom.badge %}
  <span class="badge">{{ product.metafields.custom.badge }}</span>
{% endif %}

<p>Warranty: {{ product.metafields.custom.warranty_years }} years</p>

Rich text (HTML)

The rich_text_field type renders the stored HTML unescaped — perfect for care instructions, warnings, formatted descriptions:
<div class="care">
  {{ product.metafields.custom.care_instructions }}
</div>

Boolean conditionals

{% if product.metafields.custom.is_featured %}
  <div class="featured-banner">Featured product</div>
{% endif %}

Lists

{% for tag in product.metafields.custom.tags %}
  <span class="tag">{{ tag }}</span>
{% endfor %}

{% for review in product.metafields.reviews.list %}
  <article>
    <strong>{{ review.author }}</strong>
    <p>{{ review.body }}</p>
  </article>
{% endfor %}

Money

<p>Deposit: {{ product.metafields.custom.deposit | money }}</p>

Measurements

<dl>
  <dt>Weight</dt>
  <dd>{{ product.metafields.specs.weight }}</dd>     {# "1.2 KILOGRAMS" #}
  <dt>Dimensions</dt>
  <dd>{{ product.metafields.specs.dimension }}</dd>  {# "30 CENTIMETERS" #}
</dl>

Color

<style>
  .product-card {
    border-color: {{ product.metafields.custom.brand_color }};
  }
</style>

Date

{% if product.metafields.events.launches_on %}
  <p>Launching {{ product.metafields.events.launches_on | date: "%B %d, %Y" }}</p>
{% endif %}

Reference (file)

{% if product.metafields.custom.spec_sheet %}
  <a href="{{ product.metafields.custom.spec_sheet }}">Download spec sheet</a>
{% endif %}

JSON

{% assign specs = product.metafields.custom.specifications.value %}
<dl>
  <dt>Width</dt><dd>{{ specs.dimensions.width }}cm</dd>
  <dt>Weight</dt><dd>{{ specs.weight }}</dd>
</dl>

Defensive access

Use {% if %} to guard optional fields — missing keys are falsy:
{% if product.metafields.custom.warranty_years %}
  <p>Warranty: {{ product.metafields.custom.warranty_years }} years</p>
{% endif %}
Or fall back with default:
<p>Color: {{ product.metafields.custom.brand_color | default: "#000000" }}</p>

Across owner types

Same access pattern, every owner:
{{ shop.metafields.legal.tos_url }}
{{ collection.metafields.layout.banner_color }}
{{ customer.metafields.loyalty.tier }}
{{ order.metafields.fulfilment.gift_message }}
{{ page.metafields.seo.canonical }}
{{ blog.metafields.brand.theme_color }}
{{ article.metafields.editorial.byline }}
{{ variant.metafields.specs.weight }}

Performance

Metafields are bulk-loaded server-side alongside the parent resource — one query loads the resource, one query loads all its metafields, and both are cached together under g:{storeId}:{type}:{handle} (24h TTL). There is no per-field network round-trip from Liquid. When a metafield is written via the REST API, the cache invalidation chain fires automatically (Redis g:{storeId}:* SCAN+DEL + a fire-and- forget POST to the storefront’s /api/internal/invalidate-page-cache endpoint). The next render sees the new value within ~1 second.

See also