Dynamic Components
A dynamic component is a reusable block that renders live data from your site — for example "the latest three posts tagged news" or "every author, shown as a card." The server fetches and filters the data before rendering, and exposes the rows to your component as items. Once built, you can drop the component on any page and it always shows current content. This is the fastest way to give an agent free rein over your data.
The idea
Every component has a kind. A static component is just markup. A dynamic component additionally declares one or more sources — the collections it reads. When the page renders, the server queries each source (with any filter, sort, and limit you set), and the component's template loops over the result as items.
The live collections you can bind are the same ones available everywhere: posts, authors, categories, tags, and changelog. See Live Collections for what each one contains.
Build one with an agent
The flow is: discover the source, optionally preview the rows, create the component, place it, deploy.
Discover the available sources and their fields —
list_data_sources.Preview rows before committing (optional) —
list_data_source_itemswith asource_id,filter,sort, andlimit.Create the component as
kind="dynamic". A dynamic component must declare three things together: ablock_type(the shape, e.g.list), ajs_runtime(usenonefor pure server-rendered Liquid), and a non-emptysourceslist. For example:
content_create_component
slug: latest-news
name: Latest News
kind: dynamic
block_type: list
js_runtime: none
sources: [{ source_id: "posts", default_filter: { tag: "news" }, default_sort: "-published_at", default_limit: 3 }]
html_template: '{% for item in items %}<a href="/blog/{{ item.slug }}">{{ item.title }}</a>{% endfor %}'Place it on a page —
page_insert_sectionwith the component's slug. The server fetches the bound rows and renders them.Deploy —
content_deploy_site.
items vs. the global collections
Inside a dynamic component, the rows from your declared, filtered binding arrive as items. The global collections ({{ posts }}, {{ authors }}, …) are also available in every component regardless — use those for a simple unfiltered list, and items for the component's own filtered binding.
Things to watch
All three are required.
kind="dynamic"without ablock_type, ajs_runtime, and at least one source is rejected. Set them together.Filters run on the server. The
default_filteron a source (or thefilteronlist_data_source_items) is applied before rendering. A{% if %}in your template only hides rows that were already fetched — it does not narrow the query.Some sources are singletons. The personalisation
leadfor a landing page is a single record, not a list — use it directly on a/lp/page (see Dynamic Landing Pages), not as a list binding.Directory data is coming. Binding country / city / street / business directory sources is not available yet; the blog collections (posts, authors, categories, tags, changelog) are live today.
Next steps
See what each collection contains — Live Collections.
Learn the component basics — Components.
Connect an agent — MCP Setup and the Content Tools.