Dynamic sources
Data-driven sections — smart product lists and latest posts, resolved server-side.
Some settings don’t store content — they store a query. The server runs it and hands your section the resolved, localized, currency-correct result, so a theme can offer a data-driven section (a “bestsellers” strip, a “from the journal” block) without the merchant hand-picking items or the theme calling an API.
products_by — a smart product list
The value is a small config; the resolved value is a product array shaped exactly
like the products picker (translated, prices pre-converted), so it drops into the
same product-card markup.
{ "type": "products_by", "name": "featured", "maxItems": 8 }
source |
Returns |
|---|---|
newest (default) |
Most recently created active products. |
bestselling |
Products ranked by total quantity sold. Empty until the store has orders. |
tag |
Products carrying tag (also set "tag": "summer"). |
brand |
Products of brand (also set "brand": "Acme"). |
{% for product in component.featured %}
{% render 'product-card', product: product %}
{% endfor %}
maxItems on the setting caps the count.
blog_posts — latest posts
Resolves to the most recent published posts, each with title, url, excerpt,
and coverImage — real content instead of the merchant re-typing it.
{ "type": "blog_posts", "name": "journal", "maxItems": 3 }
{% for post in component.journal %}
<a href="{{ post.url }}">
{% if post.coverImage %}<img src="{{ post.coverImage | image_url: width: 600 }}" alt="{{ post.title }}" />{% endif %}
<h3>{{ post.title }}</h3>
<p>{{ post.excerpt }}</p>
<time>{{ post.publishedAt | format_date }}</time>
</a>
{% endfor %}
Closed set, on purpose Dynamic sources are a curated vocabulary, not an open query language — the server controls exactly what each one costs and returns. That’s what lets a theme stay pure presentation while the data stays localized, converted, and safe. Need a source that doesn’t exist yet? It’s a platform addition, not a theme workaround.