Pages already gives you data tables, metric cards, charts, and form blocks — but sometimes you need a layout that doesn't fit a standard block type. A styled customer card. A KPI banner. A custom notification panel.
That's what Data-Bound HTML blocks are for.
The idea
Write HTML. Drop in {{fieldName}} placeholders. Pick a data source. The runtime fills in the values.
<div style="padding: 16px; border: 1px solid #e5e7eb; border-radius: 8px;">
<h2>{{name}}</h2>
<p style="color: #6b7280;">{{email}}</p>
<p>Status: <strong>{{data.status}}</strong></p>
</div>Point this at your customers collection and it renders a styled card for each record — with live data, no JavaScript, no build step.
How it works
- Add a Data-Bound HTML block to any page type (list, detail, dashboard, or form)
- Pick a data source — a collection or smart query, just like metric cards and charts
- Write your HTML template with
{{field}}placeholders - Publish — the runtime resolves placeholders, sanitizes the HTML, and renders it
Template syntax
| Syntax | What it does |
|---|---|
{{name}} | Inserts the name field from the record |
{{data.status}} | Dot notation — reaches into nested objects |
{{createdAt}} | System fields work too |
{{missing}} | Unresolved placeholders render as empty (no broken UI) |
That's it. No conditionals, no loops, no special syntax to learn. Just property access.
What you can build
Customer profile card
<div style="display: flex; gap: 16px; align-items: center;">
<div style="width: 48px; height: 48px; border-radius: 50%;
background: #2563EB; color: white; display: flex;
align-items: center; justify-content: center;
font-weight: 600; font-size: 18px;">
{{initials}}
</div>
<div>
<p style="font-weight: 600; margin: 0;">{{name}}</p>
<p style="color: #6b7280; margin: 0; font-size: 14px;">{{email}}</p>
</div>
</div>Dashboard KPI banner
<div style="display: flex; gap: 32px; padding: 16px;
background: #f9fafb; border-radius: 8px;">
<div>
<span style="font-size: 12px; color: #6b7280;">Total Orders</span>
<p style="font-size: 28px; font-weight: 700; margin: 4px 0 0;">{{count}}</p>
</div>
<div>
<span style="font-size: 12px; color: #6b7280;">Revenue</span>
<p style="font-size: 28px; font-weight: 700; margin: 4px 0 0;">${{total}}</p>
</div>
</div>Status indicator
<div style="display: inline-flex; align-items: center; gap: 8px;
padding: 4px 12px; border-radius: 9999px;
background: #dcfce7; color: #166534; font-size: 14px;">
● {{data.status}}
</div>Security
Data-bound HTML uses the same sanitization pipeline as static HTML blocks — DOMPurify strips all script tags, event handlers, and XSS vectors before rendering. The template engine only supports property access — no function calls, no code execution.
Your users write HTML. The platform handles security.
When to use it
| Scenario | Best block type |
|---|---|
| Table of records | Data Table |
| Single record fields | Field Display |
| Charts and metrics | Chart / Metric Card |
| Custom styled layout with live data | Data-Bound HTML |
| Static content (no data) | Static HTML or Markdown |
Data-bound HTML fills the gap between "I need a quick data table" and "I need to build a custom React component." It's the middle ground — full control over layout, powered by live data, no code required.
Try it
Open any page in the editor, add a Data-Bound HTML block, pick a collection, and start writing. Your template renders instantly in the published page.