Skip to main content

Widgets

Widgets are reusable pieces of HTML and logic that you can drop into any template. Think of them as mini-components.

What is a widget, exactly?

A widget is a Handlebars partial. A partial is just a reusable chunk of HTML. When you write {{> InvoiceStatus}} in your template, Handlebars replaces it with the HTML from the InvoiceStatus widget.

Some widgets also come with:

  • CSS styles that get bundled with your template
  • Helpers (JavaScript functions you can call from your template)

Available widgets

WidgetWhat it doesHow you use it
InvoiceStatusShows a colored status tag (Paid, Overdue, Draft, etc.){{> InvoiceStatus}}
DemoBadgeShows a diagonal "Demo" watermark on the page{{> DemoBadge}}
DateTimeProvides date formatting helpers with timezone support{{formateShortDateWithOffset date offset}}
MarkdownViewerRenders markdown text as styled HTML{{> MarkdownViewer (prepareMarkdownViewerData text)}}

How to use a widget in your template

Two steps:

1. Import it in your index.ts

import "../../widgets/invoice-status";

This runs the widget's code, which registers the Handlebars partial. Without this import, the {{> InvoiceStatus}} tag in your template will silently produce nothing.

2. Use it in your template.hbs

{{> InvoiceStatus}}

That is it. The widget handles the rest.

How widgets are built

Each widget lives in src/widgets/<name>/ and has:

src/widgets/invoice-status/
index.ts # Registers the partial and helpers
template.hbs # The HTML (optional, some widgets build HTML in JS)
styles.css # The styling (optional)
version.json # Auto-managed version

When a widget registers itself, it calls Handlebars.registerPartial():

Handlebars.registerPartial("InvoiceStatus", compiledHTML);

And optionally registers helpers with Handlebars.registerHelper():

Handlebars.registerHelper("computeInvoiceStatus", function(status, ...) {
// return computed data
});

Widget vs template

WidgetTemplate
What it isA small, reusable pieceA full document layout
Registered asHandlebars.registerPartialwindow.CeresTemplate
Can be used byAny templateOnly the main renderer
Has its own CSS?YesYes
Has its own build output?Yes (separate bundle)Yes (separate bundle)