The components

Last updated 14 August 2026

The eleven portal component types laid out on a grid, from data grid and metric to map, form, HTML and modal

Components live in the rail on the left of the builder. Drag one onto the page and configure it in the panel on the right.

The eleven, at a glance

Component Lands at Fed by For
Data grid full width, 14 rows a report a table of the customer's records
Metric quarter width, 5 rows a report one figure, with something to read it against
Chart half width, 12 rows a report a line, bar or pie
Calendar two thirds, 16 rows a report appointments, jobs, deadlines
Map half width, 12 rows a report locations, and pins customers can drop
Form half width, 12 rows a form letting a customer send you something
Button 6 columns, 2 rows going to a page, opening a dialog, or a link
Heading full width, 2 rows a title
Text full width, 4 rows a paragraph
HTML full width, 8 rows your markup anything the rest cannot do
Modal not on the page markup or a form a dialog something else opens

The five report-fed components all need a Data Grid report, never an HTML one. See Data and reports.

Data grid

A table of rows, paged, with the report's own columns and formatting.

Setting What it does
Report a Data Grid report. Required
Records Limit rows per page. Default 20
Order By Column one of the report's columns
Order Direction ascending or descending

Ordering is optional, and optional together: a report that already orders itself needs neither.

A cell is drawn as the report wrote it, formatting and links included. That is usually what you want, and it has one consequence worth checking: a report built for staff often contains links to staff screens, which on a portal lead to the sign-in page. A report meant for a portal wants its own column formatting.

Metric

One number, with something to read it against. The report returns one row, and its columns fill the card's slots.

Setting What it does
Report a Data Grid report returning one row. Required
The number the column holding the figure. Required
Beside the number short text from a column, such as 6 applications
Compared with an earlier figure. The difference is worked out for you
A rise means Things are better or Things are worse, so a rise is green or red
Colour Plain, Blue, Green, Amber, Red, Purple, or From a column
Colour from a column required once the colour comes from the report
When the card is clicked nothing, open a modal, or open a page

Three things worth knowing:

  • Formatting stays in the report. Rounding, currency symbols and percent signs are the report's decisions, so the card shows the figure exactly as it arrives.
  • No row is not a zero. A report returning nothing for this customer draws an empty note rather than a confident 0.
  • The card is the whole component. Its name is drawn along the top of the card, so naming it never wraps it in a second box.

When a click opens a modal, the report row travels with it, keyed by the report's own column names. Rename a column and the dialog reads a different key.

Chart

A report, plotted. The chart type is chosen first, because it decides which of the other settings apply.

Setting Applies to
Report all. Required
Chart Type Line, Bar or Pie. Required
Records Limit line, bar. Default 20
Order By Column and Order Direction line, bar
Horizontal (x) axis line, bar. Required
Vertical (y) axis line, bar. Required, and takes more than one column
Slice labels and Slice values pie. Both required

A pie hides the limit and the ordering deliberately: a slice is read as a share of a whole, so plotting the top 20 of 200 rows would put a percentage under every slice that is a share of nothing anybody asked about.

The vertical axis is the one setting that takes several columns, because a line chart comparing two measures is an ordinary thing to want.

Charts are drawn by the same renderers as the CRM's own dashboards, so a report plotted here and the same report plotted on a dashboard look alike.

Calendar

Appointments, jobs, renewals and deadlines, from a report.

Setting What it does
Report a Data Grid report. Required
Event name the column holding the title. Required
Starts on the date column. Required
Starts at the time column. Leave it empty and every event is a whole day
Ends on and Ends at optional
Event ID the record's own id, handed to whatever a click opens
Colour a column returning a CSS colour, such as #0b84cf
Opens on Month, Week or List
Clicking an event nothing, open a modal, or open a page

Date and time are separate columns, because reports keep them separate. The time is what makes a row a moment rather than a whole day, and that is decided per row, so one calendar legitimately holds both.

The visible month reaches your report. As the customer navigates, the range on screen is available to the report's SQL as {{ range.from }} and {{ range.to }}, so a schedule query can return one month at a time rather than the first few hundred rows of everything.

When a click opens a modal, the event travels with it keyed by role (id, title, start, end, startDate, startTime, endDate, endTime), so renaming a report column does not break the dialog.

Map

Locations as pins, from a report.

Setting What it does
Report a Data Grid report. Required
Latitude column and Longitude column required
Column with the marker name optional
Column shown when a marker is clicked optional
Zoom default 4
Group markers that overlap draws crowded pins as one numbered circle
Let customers drop and edit a pin turns the map into an input
Send the pin to this address required once pins are on
Column holding the location ID needed to edit existing locations

A row whose coordinates are missing or out of range is dropped rather than drawn, so an incomplete row does not put a marker in the Atlantic. A map shows up to 200 markers and has no paging, deliberately: every marker is drawn at once or the picture is a lie about where things are.

Dropped pins are posted to a dynamic endpoint of yours. The address is read on the server and never reaches the page, so nobody can post fabricated coordinates to it from outside the portal. Your endpoint receives the position, the name and description, the location id if there is one, and who is signed in. Answer with the saved record's id ({"id": 123}) and the customer can edit that pin afterwards.

Form

An existing Flexie form, drawn into the page.

Setting What it does
Full width, as tall as its content recommended for anything but the shortest form
Form the form to show. Required

Only published external forms can be used. An internal form is filled in by staff against a record they have open, so it has nothing to open against on a portal.

The form knows who is signed in, so fields matching the customer's own record are prefilled. Submissions arrive exactly as they do from your website, which means every workflow already listening to that form keeps working. See Forms.

Button

Setting What it does
Label required
Does Opens a page, Opens a modal, or Opens a link
Page, Modal or Address whichever the action needs. Required
Style Primary, Secondary or Link

Heading

Setting What it does
Content the text. Required
Size Large, Medium or Small

Text

Setting What it does
Content a paragraph. Line breaks are kept

A heading and a paragraph are their own content, so neither is drawn in a panel until you give one a name, which needs a title bar to live in.

HTML

Your own markup, rendered on the server against the signed-in customer.

Setting What it does
Wrap the component on by default. Turn it off and there is no panel at all: what the page shows is exactly your markup
Full width, as tall as its content for a document whose length varies per customer
Content the markup, written in the built-in editor

This is the escape hatch, and it has a page of its own: HTML components. What that markup can call is The JavaScript API.

A dialog. It is not placed on a page: it sits in the modal tray and is opened by something else: a button, a calendar event, a metric card, or your own script.

Setting What it does
Title required
Opens When something opens it, As soon as the page is shown, or On a named event
Event name required for the third
Width Standard or Full width
Content from Written here or A form
Form required when it holds a form
Content required when the markup is written here

Exactly one of the last two is ever asked for, and a modal holding neither is the configuration mistake with no symptom on the page: it sits in the tray looking finished, and the first person to meet it is a customer who clicks something and gets an empty dialog. Publishing refuses while one is in that state, and the tray marks it.

A modal is refetched every time it opens, so it always shows current data and its script always sees the parameters it was opened with.

Which one, for the common asks

The ask The component
"Show my customers their invoices" Data grid
"Put their balance at the top" Metric
"Show spend over the year" Chart
"Show their upcoming appointments" Calendar
"Let them tell us where to deliver" Map with pins on
"Let them request something" Form
"Show them a document made from their own data" HTML, full height
"Let them open a detail view from a row" Modal, opened by a click