Enable platform widgets · option 3 · demo

Platform-drawn KPI cards

The platform draws the designer's card itself, from numbers its own server reads out of Metabase with a signed, locked request. Every pixel of the cards below is this page's HTML, so the design is fully under the platform's control.

Demo numbers. They are generated inside Metabase by three dummy-data questions and are not Enable figures.

KPI cards

Demo scope

The filter values live inside a signed token on the server. This page can only ask for one of three scopes that were signed in advance; it cannot change a filter, and the server refuses any other value without calling Metabase.

Accommodation rate

—

Approval rate

—

Conversion rate

—

Reading live numbers from Metabase…

How it works

  1. Server signs. The platform's server signs a short-lived token naming the question and every locked filter (whitelabel, merchant, application). The signing secret never leaves the server.
  2. Server fetches. It calls Metabase's signed data request, GET /api/embed/card/<token>/query, server to server. Metabase answers no other site's browser (it sends no cross-origin headers), so this step cannot happen in the page.
  3. Server hands rows to the page. It returns only the columns and rows the card needs, from its own address (/api/widgets here).
  4. Page draws. The page turns rows into the label, the value, the change and the line, and draws the card exactly as designed.

Every code block below is fetched from the file this demo actually runs, so it cannot drift from what you see working above.

1. Sign on the server

HS256 over resource.question, params (every locked filter, one value each) and exp. File: /code/sign-token.js.

Loading…

2. Fetch on the server

The demo's server is a Cloudflare Pages Function. It holds three finished, expiring tokens per scope as a Cloudflare secret, never the signing secret. File: /code/widgets-handler.js (re-exported by functions/api/widgets.js).

Loading…
Loading…
Loading…

3. What the page receives

The response this page just received from /api/widgets (first two rows of each widget shown). Decimal cells arrive as JSON strings ("0.468800"): parse every numeric cell with Number(), and treat null or "" as "no value", never as zero. Window dates roll daily.

Loading…

4. Draw in the page

Value = the latest window's rate as a whole percent. Change = relative change against the previous window, the same arithmetic as Metabase's trend widget. File: /js/card.js.

Loading…
Loading…
Loading…

Rules