Embed a live model

Turn a Valem model into an interactive widget on someone else’s page — a blog post, a docs site, a Notion doc, or your own React app. The reader changes an input and every derived value recomputes live, with no spreadsheet and no backend of their own.

  1. Two ways to embed
  2. The iframe snippet
    1. Auto-resize (optional)
  3. The React component
  4. Interactive vs read-only
  5. How it works, and what it means for privacy
  6. Related

Two ways to embed

Both carry the model in the link itself and compute against a Valem sandbox origin (the public sandbox by default). Each viewer gets a private, ephemeral copy — their edits are never saved or shared back to you or to other viewers.

Surface Use it when Build step
<iframe> snippet Any HTML host — a blog, a CMS, Notion, a plain page. None.
@valem/embed React component A React app that wants native mounting, callbacks and theming. npm.

The iframe snippet

In the sandbox, open a model and choose Share → Embed. Pick Interactive or Read-only and a theme, then copy the snippet:

<iframe src="https://valem.onrender.com/embed.html#e=1.q7Fh…"
  style="width:100%;border:0" height="480" loading="lazy"
  sandbox="allow-scripts allow-forms allow-same-origin"
  title="Valem model"></iframe>

Paste it anywhere. The whole model travels in the #e=… fragment, so there is nothing to host and nothing to keep in sync.

Auto-resize (optional)

The frame reports its content height to the host. Paste this once per page to size the iframe to fit:

<script>
  window.addEventListener('message', function (e) {
    if (e.origin !== 'https://valem.onrender.com') return;
    if ((e.data || {}).type !== 'valem:height') return;
    document.querySelectorAll('iframe').forEach(function (f) {
      if (f.contentWindow === e.source) f.style.height = e.data.px + 'px';
    });
  });
</script>

The React component

npm install @valem/embed
import { ValemModel } from '@valem/embed';

export function Pricing() {
  return (
    <ValemModel
      spec={pricingSpec}          // an inline ModelSpec — or pass embedRef="1.q7Fh…"
      mode="interactive"
      theme="auto"                // 'light' | 'dark' | 'auto'
      height="auto"               // or a fixed pixel number
      onChange={(state) => console.log(state)}
      onConstraintFlag={(violations) => console.warn(violations)}
    />
  );
}

react / react-dom (v18+) are peer dependencies. The component is lazy by default — it defers creating the model until it scrolls into view, so a page with many embeds doesn’t fire every model create on load. See the package README for the full prop list.

Interactive vs read-only

  • Interactive (default) — the viewer edits inputs and derivations recompute live.
  • Read-only — the view renders with inputs disabled: a computed snapshot for showing a result (a filled-in pricing table, a finished calculation) without letting readers change it.

How it works, and what it means for privacy

The spec travels in the URL fragment, which browsers never send to a server. On load, the embed creates a fresh throwaway model on the Valem server from that spec and renders the live view against it — derivations and constraints compute server-side, exactly as in the sandbox. Nothing is persisted; the instance expires on its own.

Because the model is in the link, anyone who can see the page can read whatever the spec (and, if you chose Spec + data, the entered values) contains. Share spec-only unless you intend the data to be public.