Webapps
A webapp is a published, multi-page application assembled from dashboard cards and content blocks. Where a dashboard is a single canvas of cards for an authenticated audience, a webapp is the customer-facing surface: a small navigable app with its own pages, navigation, and token-gated public share links so people outside the platform can view it without a login. It is Honeyframe's "ship a SaaS app from your data" surface, modeled on Dataiku's code-webapps but built no-code from the same governed blocks the rest of the platform uses.
Webapps run on the shared block architecture — every block renders through the same renderer as a dashboard card, all SQL stays server-side, and PII masking applies on every path (including anonymous public viewers). No arbitrary server code runs; the "code" in a code-card is a governed read-only SELECT, never browser-supplied SQL.
Webapps vs dashboards
| Dashboard | Webapp | |
|---|---|---|
| Shape | One canvas of cards (with pages/tabs). | A multi-page app with its own nav. |
| Building block | Cards (SQL → chart). | Page blocks — card references, HTML, and code-cards. |
| Audience | Authenticated platform users with dashboard.read. | Internal users and anonymous viewers via a public share link. |
| Sharing | Per-link public tokens on a single dashboard. | Per-link public tokens on the whole app; share links resolve to a dedicated public route. |
| Authoring | Drag-and-drop dashboard editor. | No-code webapp builder (full-width canvas). |
A webapp can embed a card from a dashboard without that dashboard being public — the webapp itself is the access grant. Only cards a webapp actually references can be executed through it; there is no arbitrary-card read.
The webapp builder
The webapp builder is a full-width canvas (it is not boxed into the centered content width that other editors use). You assemble the app from pages, give each page a set of blocks, and define the app's navigation. Each page lays its blocks out on a 24-column content grid.
Authoring affordances:
- Add a block — the Add panel carries tabs for the block kinds below (card reference, HTML, code-card).
- Per-block editors in the right rail — each block kind has its own editor (e.g. the code-card editor exposes the SQL, chart type, and display-option form).
- Live preview — code-cards preview their draft SQL before you save via a Run preview action, so you see the chart while you iterate rather than only after a save.
- Filter-aware header chips — pages can carry header signals (a meta line and an alert line) driven by SQL, and a filter bar whose options can be static or sourced from a
SELECT(a dynamic branch/segment selector). Blocks opt into receiving the page filters.
Responsive content grid
In the viewer, the page content grid collapses to a single full-width column below 767px (blocks flow in source order, so array order is reading order), matching the shell nav's breakpoint where it collapses to a drawer. The reflow is presentational only — the authored desktop layout is unchanged.
Blocks & card types
A page's content is an ordered array of blocks. Each block has a kind; a block with no explicit kind is treated as a card reference for back-compat, so older configs parse unchanged.
| Block kind | What it is |
|---|---|
page | A page in the app — a titled container holding an ordered list of blocks. |
card_ref | A reference to an existing dashboard card. Renders that card inside the app; the source dashboard need not be public. |
html_block | A custom HTML block. Two modes: sanitized (DOMPurify, no JS — the default) and sandboxed (rendered in a no-same-origin iframe, so JS can run but is fenced off from cookies, tokens, and the API). |
code_card | A governed code-card: a read-only SELECT whose result renders as a chart. The SQL is the server-side source of truth and is never sent from the browser; it runs under a single-statement read-only guard. |
nav_item | A navigation entry — a label and a path that link to a page in the app's nav. |
Sandboxed HTML blocks bypass PII masking by design (they render arbitrary markup), so the builder marks them with a "Custom HTML · not PII-governed" badge.
Code-card types
Code-cards render through the same DashboardCardChart renderer as dashboard cards and accept the same card_config / display_options shape. The builder exposes a registry-driven display-options form (legend, number format, sort, percentage, color scale, pie size, etc.) plus a guarded Advanced config (JSON) editor for type-specific column mappings (a malformed edit is rejected rather than blanking a valid config). The code-card type list includes histogram, choropleth, dot_strip, scorecard_heatmap, stat_funnel_plot, spc_control_chart, geo_scatter, and process_map.
process_map (v0.1.8)
process_map renders an identity / relationship / process graph from a governed SQL edge-list — a result set of transitions between nodes. It shipped first as a dashboard card type in v0.1.7 and became a no-code code-card in the webapp builder in v0.1.8, so an author can drop a relationship graph onto any app page from a governed SELECT without writing code.
The renderer is a single SVG (rounded-rect nodes with fill proportional to volume, cubic edges with arrowheads and weight labels) using a dependency-free layered layout. Its display options include show_edge_labels, edge_weight (count / percent / avg_hours), min_edge_count (a noise filter — dropped edges surface in the footer rather than vanishing silently), layout_direction (TB / LR), and show_node_counts. It accepts either a raw event log or a pre-aggregated edge-list and auto-detects which it was given.
This is the no-code path for the "interactive relationship graph" use case (for example, surfacing fragmented identities across systems from a governed edge-list). For a fully custom interactive graph, a sandboxed html_block is the code-webapp escape hatch — at the cost of bypassing masking, so embed only already-masked data.
Publishing & share links
Webapps are published assets. Publishing is opt-in — an app stays a draft until you publish it. Publish and unpublish are both reversible.
Sharing works exactly like dashboard public links, scoped to the whole app:
- Open the Share modal in the builder to mint a public link. The raw token is shown once on creation — copy it then; the list view never re-displays the plaintext (tokens are hashed at rest).
- Each link carries an optional label, an optional expiry, and view tracking (count + status). Revoke is immediate, idempotent, and isolated per app.
- A share link points at a dedicated anonymous route. The public URL carries the token as a query parameter (
/public/apps/{key}?token=...); the viewer drives the PII-masked public endpoints with no platform login. - A valid share token is the access grant even when the app's global public flag is off; PII masking still applies to token viewers, and expired or revoked tokens return a uniform 404.
Page info (titles, header signals, nav) is editable from the builder, so you can adjust copy and navigation without re-publishing the underlying cards.
Building from code
The Python SDK (honeyframeapi) can publish and build webapps end to end. The quickest path publishes an existing dashboard as a webapp and mints a share link:
webapp = client.publish_webapp(...)
link = webapp.create_public_link()
print(webapp.public_url(link.token)) # shareable URL
webapp.revoke_public_link(link.token)
To assemble a multi-page app from blocks (including a process_map code-card) and create it in one call, use the page and block builders:
from honeyframeapi import page, card_ref, html_block, code_card, nav_item
webapp = client.create_webapp(
name="Ops console",
pages=[
page("Overview", blocks=[
html_block("<h1>Operations</h1>"),
card_ref(dashboard_id="...", card_id="..."),
]),
],
nav=[nav_item("Overview", "/overview")],
publish=True, # opt-in; draft by default
)
A Webapp handle also supports incremental edits — update, publish / unpublish, add_page, set_nav, and the share-link helpers above. See the SDK reference for the full signatures: SDK → Dashboards and webapps. For card authoring concepts, types, and card_config shapes that code-cards reuse, see Dashboards.