Skip to main content
Version: v0.1.8

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

DashboardWebapp
ShapeOne canvas of cards (with pages/tabs).A multi-page app with its own nav.
Building blockCards (SQL → chart).Page blocks — card references, HTML, and code-cards.
AudienceAuthenticated platform users with dashboard.read.Internal users and anonymous viewers via a public share link.
SharingPer-link public tokens on a single dashboard.Per-link public tokens on the whole app; share links resolve to a dedicated public route.
AuthoringDrag-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 kindWhat it is
pageA page in the app — a titled container holding an ordered list of blocks.
card_refA reference to an existing dashboard card. Renders that card inside the app; the source dashboard need not be public.
html_blockA 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_cardA 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_itemA 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.

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.