← Back to all posts
3 min readCentrali Team

Data-Bound HTML: Custom Layouts Powered by Live Data

Write HTML templates with {{field}} placeholders that render live collection data. Build custom cards, banners, and layouts without writing JavaScript.

FeatureProduct

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.

html
<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

  1. Add a Data-Bound HTML block to any page type (list, detail, dashboard, or form)
  2. Pick a data source — a collection or smart query, just like metric cards and charts
  3. Write your HTML template with {{field}} placeholders
  4. Publish — the runtime resolves placeholders, sanitizes the HTML, and renders it

Template syntax

SyntaxWhat 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

html
<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

html
<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

html
<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

ScenarioBest block type
Table of recordsData Table
Single record fieldsField Display
Charts and metricsChart / Metric Card
Custom styled layout with live dataData-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.

Building something with Centrali and want to share feedback about this feature?

Email feedback@centrali.io