Embedding

Embed Elements and Dashboards into customer React apps, third-party websites, and mobile WebViews from a single renderer.

Anything you build in Aeontel — an Element, a Dashboard, a form — can be rendered outside the platform. The same renderer powers three surfaces: a React component dropped into a customer's own app, an iframe-friendly HTML page hosted by Aeontel, and a mobile WebView. One artifact, one auth model, one rendering pipeline.

The artifact stays an Element (or Dashboard). Embedding is what you do with it.

Three surfaces, one renderer

<Element> and <Dashboard> from @aeontel/react

For customers running their own React app, @aeontel/react exports component primitives that fetch the artifact and render it natively in the host tree:

TSX
import { Element, Dashboard } from "@aeontel/react";

<Element id="elm_xxx" embedToken={token} />
<Dashboard id="dsh_xxx" embedToken={token} />

<Element> is the atomic case — a single widget (form, chart, table, custom Element). <Dashboard> composes multiple Elements via MDX. Both ship with the host's React, share its theme tokens, and can hook into native interactions (form submission, click handlers).

For framework-mismatched hosts or stricter security boundaries, <EmbedFrame> is an iframe-based escape hatch with the same API and token model.

platform.aeontel.com/embeds/*

For iframes on third-party sites, mobile WebViews, or any consumer that wants a self-contained URL, Aeontel hosts a stripped renderer at platform.aeontel.com/embeds/{id}. The page boots the same renderer used inside the platform, minus the sidebar, header, and admin chrome.

html
<iframe src="https://platform.aeontel.com/embeds/elm_xxx?token=..." />

The route lives under platform.aeontel.com rather than a separate domain so cookie-based auth works for first-party consumers (mobile WebView, same-origin iframes) without CORS configuration. For third-party iframes, the visibility ladder below applies.

Mobile WebView

The mobile app's "Dashboards" tab loads platform.aeontel.com/embeds/dashboards inside a WebView. Auth flows through a one-shot session exchange: the app passes a short-lived token, the embed surface sets the platform session cookie, and subsequent navigation + in-page Element fetches authenticate via cookie.

Native rendering of Elements is not on the table — Elements are web React (DOM, CSS, charts), and the WebView is the renderer.

Visibility ladder

Embeddable entities (Elements, Dashboards, Forms) carry a visibility field that determines who can render them and how:

  • private — platform-only. Cookie auth, must be signed in to the workspace.
  • public — anyone can render. Anonymous, rate-limited. Forms are the canonical case: write-scoped, no data leak risk, fits clean on a marketing page.
  • protected — token-gated. Host page mints a signed embed token server-side (using the workspace's API secret key) and passes it via prop or URL. The renderer exchanges the token for a short-lived session.

Visibility is enforced at the renderer level, not per-Element-author — the same Element rendered in three contexts respects the same ladder.

Auth model

Auth depends on whether the embed is first-party (same origin as platform.aeontel.com) or third-party (iframed on a customer's domain).

First-party — mobile WebView, same-origin iframes. The browser treats the embed as same-site with the platform; cookies flow normally; CORS is satisfied because api.aeontel.com is already in the platform's allowed origins.

Third-party — iframe on acme.com, <Element> rendered in a customer React app. The browser treats the embed page as cross-site regardless of where it's served from, so cookies are blocked. Auth flows entirely via embed tokens:

  1. Customer's backend mints a token using its workspace API secret key, scoped to a specific Element/Dashboard and TTL.
  2. Token is passed to the embed surface (URL parameter for iframes, prop for <Element>).
  3. The renderer exchanges the token for a short-lived session, fetches the Element and its bound data, and renders.

Public-visibility Elements skip the token step entirely.

When to use which surface

Use caseSurface
Customer's React app, native feel, theme integration<Element> / <Dashboard>
Customer's React app, isolation from host CSS/version churn<EmbedFrame>
Marketing site, SaaS dashboard, any non-React host<iframe src="…/embeds/…">
Mobile (Aeontel app or partner app)WebView pointing at /embeds
Workspace internal dashboardsPlace the Element on a workspace Page; no embedding

Why not a separate domain or worker?

Embed routes live on platform.aeontel.com rather than a dedicated embed.aeontel.com worker. The reasons:

  • Same-origin as the API for first-party consumers — cookies work, no CORS edge cases.
  • Reuses the existing renderer, query client, and auth middleware — no duplication.
  • Bundle isolation is achieved through code-splitting and a stripped layout, not through deploy boundaries.

If deploy coupling or bundle size become load-bearing concerns, the embed surface can move to its own worker without API changes — the renderer is the same package either way.

What this unlocks

A customer builds a form in the platform's Element editor. They drop <Element id="elm_xxx" /> on their marketing site. Their backend mints embed tokens; the form renders natively in their React tree; submissions land in their workspace with schema validation, storage, and downstream triggers. They never call the Aeontel API directly.

The same model applies to dashboards (embed analytics in customer apps), forms (embed contact/intake/feedback widgets anywhere), and any future Element that wraps a workspace primitive. Aeontel becomes a backend-for-frontend without exposing the API surface to the host.