Introduction & How it Works
What Dynamic Data is, tag syntax, the picker UI, template contexts, and the two patterns (Smart Element vs Primitive + Tag).
Dynamic Data is a placeholder system that auto-fills with real data at render time. You write a tag like {product_title} in a text/link field; when a visitor opens the product page, that tag becomes the actual product name.
Core benefit: 1 template = many pages. Build one Single Product template — every product reuses it, with per-product data injected automatically.
Syntax
Two forms with different rules:
Single brace — {tag_name}
For entity data — either the main entity of the page or the current row of a Query Loop. Examples: {product_title}, {post_content}, {site_name}. The same tag resolves the page-level entity in a single template (e.g. Single Product) AND the per-iteration row inside a Query Loop — there is no separate syntax for the two cases.
Double brace — {{loop.*}} (loop metadata only)
Reserved for loop metadata that has no entity equivalent: {{loop.index}}, {{loop.number}}, {{loop.count}}, {{loop.first}}, {{loop.last}}. Only valid inside elements with queryLoop.enabled = true.
{{loop.*}} outside a Query Loop won't resolve (the raw {{...}} stays as text). Single-brace tags also don't resolve in contexts that don't expose them.
How to Use — The Picker
On every text/link field that supports dynamic data, a small { } icon (database) appears in the top-right corner. Flow:
- Click the
{ }button — the popover opens. - It auto-filters tags valid for the current template (e.g. inside a Single Product template you see
product_*tags). - If the parent element uses Query Loop, the picker also surfaces entity tags for the loop's data source AND the
{{loop.*}}metadata group. - Click a tag — it's inserted into the field. If the tag has a suggested filter (e.g.
{product_price_raw}gets|currency), the filter is appended automatically.
Fields That Support Dynamic Data
Not every input accepts tags. Only fields flagged hasDynamicData: true in the control spec. Common ones:
- Heading —
text(plain mode),link - Basic Text —
text,link - Rich Text —
body - Button —
text,link,whatsappMessage - Image —
src,alt,link,whatsappMessage - Text Link —
text,link - Menu —
brand.text,brand.tagline,items[*].label(recursive) - Product Image Gallery —
featuredImageSrc,galleryImagesSrc
Template Contexts
Every template type maps to one context, which decides which tags resolve. Reference:
| Context | Applies to template | Resolves |
|---|---|---|
product | single_product, single_bundle | {product_*} + {site_*} |
post | single_post | {post_*} + {site_*} |
page | single_page | {page_*} + {site_*} |
course | single_course | {course_*} + {site_*} |
archive | post_archive, shop_catalog, course_archive | {archive_*}, {post_count} |
loop | inside a queryLoop.enabled element | Entity tags of the loop's data source ({product_*} / {post_*} / {course_*}) + {{loop.*}} metadata + {site_*} |
global | section, header, footer, checkout, etc. | {site_*} only |
Two Patterns: Smart Element vs Primitive + Tag
Two ways to render dynamic data — pick by need:
Pattern A — Smart Element
Dedicated elements auto-filled from context. No text field to type into.
productTitle— renders product name. Props:level(h1–h6),alignment,linkToProduct.productDescription— renders description. Prop:plainText(boolean).postTitle,pageTitle,courseTitle— analogous for post/page/course.
Use when you only need to display data as-is — fastest set-up, minimal props.
Pattern B — Primitive + Tag
Use a generic element (heading, basicText, richText) and insert a tag via the picker.
Buy {product_title} now!
Use when you need composition: static text + tag + filter, or custom formatting (bold mid-title, etc.).
Next: Tags & Filters Reference for the full catalog, or Common Recipes & Patterns for copy-paste snippets.