Live code playgrounds

Embed
Preview of the card
<a href="https://forumulate.com/guides/live-code-playgrounds"><img src="https://forumulate.com/guides/_api/public/orgs/046a9bc0-d530-43ae-9bae-af7945008cda/spaces/36aa4df0-1e95-4cef-8ae9-795169441345/pages/3a2ef7fb-d5b2-4ead-a072-f42eb179be28/social-card.svg?v=3e7ae33eec8b" alt="Live code playgrounds" width="600" height="315"></a>

A Code demo (the playground block) puts runnable code on a page: editors for the source beside a live preview, a Run button, a Reset button, and the console output under it. Readers can change the code in their own copy and run it again; your version is never touched. It is the block to use for "try this easing curve", "here is the component, change the props", or a CSS trick a picture cannot show.

Playgrounds come in two runtimes:

runtime

What the JS editor holds

What runs

unset (or html)

Plain JavaScript, beside HTML and CSS

Your HTML, CSS and script, as a small web page

react

JSX or TypeScript (the editor tab reads JSX)

Your code compiled in the sandbox and run with React 19; its default export is mounted as the page's root

Before you build on this: demos only run once Forumulate has configured the sandbox domain they run on. Until then readers see the block's fallback picture. See What you need to set up.

Adding one

In the page editor, type / and choose Code demo (under Advanced). The block's settings panel, Code and fallback, holds:

  • Title — a heading over the demo ("Easing, side by side").

  • Runs as — HTML, CSS and JavaScript, or React (JSX, default export is mounted).

  • The HTML, CSS and JavaScript (or JSX) sources, up to 20,000 characters each.

  • Layout — Side by side, Stacked or Preview only.

  • Readers may edit the code — off makes the editors read-only and removes Reset.

  • Preview height (px) — 120 to 1200, default 320.

  • Fallback picture readers see and Fallback picture described — the picture shown while the demo loads, and instead of the demo when demos cannot run.

The attributes, the JSON form and the markdown form are listed in the authoring reference under playground.

Plain HTML, CSS and JavaScript

:::playground{title="Easing" layout="split" fallback="/api/assets/p1" fallbackAlt="Two boxes, one easing out"}
```html
<div class="box"></div>
```
```css
.box { width: 48px; height: 48px; background: #6d28d9; transition: transform .3s ease-out }
.box:hover { transform: translateX(120px) }
```
```js
console.log('ready')
```
:::

The sources are ordinary fenced code blocks tagged html, css and js (the JSX of a React demo is tagged js too). Only the sources you set get an editor. noedit makes them read-only; tabs="js,html" orders the editors.

React components (runtime: "react")

With runtime="react" the JavaScript editor holds a module in JSX or TypeScript. It is compiled inside the sandbox (TypeScript types and JSX are stripped and the module is turned into plain JavaScript there, in the reader's browser) and then run. If the module has a default export, it is rendered as a React component into #root.

:::playground{title="A counter" runtime="react" fallback="/api/assets/p2" fallbackAlt="A button reading Clicked 3 times"}
```js
import { useState } from 'react';

export default function Counter({ start = 0 }: { start?: number }) {
  const [n, setN] = useState(start);
  return <button onClick={() => setN(n + 1)}>Clicked {n} times</button>;
}
```
```css
button { font: 600 16px system-ui; padding: 8px 14px; border-radius: 8px }
```
:::

The rules of the React runtime:

Topic

Rule

Imports

react, react/jsx-runtime, react-dom and react-dom/client are available. Nothing else can be imported: there is no package registry and no network inside the sandbox.

Mounting

The default export is rendered into the element with id="root". With no HTML source, the page is <div id="root"></div>. If you write your own HTML, keep a #root element in it.

No default export

The module still runs; nothing is mounted. Useful for a script that draws into your own HTML.

JSX

The automatic JSX runtime: you do not need import React.

Errors

A compile error, or the React runtime failing to load, is printed in the demo's console under the preview, so a reader sees why nothing rendered.

CSS

The CSS editor works as it does in a plain demo, and styles the whole demo page.

Where the code runs, and why

A playground runs code you (or any editor of the space) wrote, and code a reader typed. Neither may ever run with a reader's session. So demo code never runs on your site's address, on a custom domain, or on forumulate.com:

  • It runs in an <iframe sandbox="allow-scripts"> loaded from a separate sandbox domain — a different registrable domain from ours, so no cookie of ours can reach it.

  • The demo page's own policy allows inline code and drawing, and forbids everything else: no fetch, no websockets, no beacons, no form posts, no navigation. Images from https: addresses, and data: and blob: media, still load.

  • The React runtime itself is served from that same sandbox domain and nowhere else; on any other address its file is a 404.

  • The demo starts when it scrolls into view, and the preview's height is reserved before it loads, so the page does not move.

What you need to set up

Nothing on your side. Playgrounds need a sandbox domain on Forumulate's side: a separate registrable domain pointed at our reader service. A subdomain of ours is refused on purpose, because it would share cookies with the reader; the feature stays off rather than run unsafely.

Until Forumulate has configured it:

  • Your code is saved with the page (both runtimes), so every playground you write starts working the day the sandbox domain does, with no change on your side.

  • In the editor, the block says "Interactive demos need a sandbox domain — not yet available", and explains that readers see the fallback picture.

  • Readers see only the fallback picture (with its caption), or nothing at all when the block has none. The code is never put into the page, because a page that cannot run it should not show a dead editor.

So give every playground a fallback picture: a screenshot of the demo's end state is enough. It is also the poster readers see for the moment before a running demo loads.

Once the sandbox is live, the editor's note changes to "Readers can run and edit this demo", and readers get the editors, the preview, Run, Reset and the console.

Styling

The block carries data-fx-playground, so customCss and elementStyles can reach it (the fallback figure too). Inside a running demo, only the demo's own CSS applies: the sandbox page does not load your theme.

The Forumulate teamUpdated