@ox-content/code-play
v3.2.11
Published
Opt-in Code Play plugin for on-demand documentation sample execution
Maintainers
Readme
@ox-content/code-play
Opt-in Code Play plugin for Ox Content. It runs documentation samples on demand and exposes a headless API plus Headless / preset UI.
Nothing runs until you install this package and enable specific languages.
Pages without matching play blocks do not load ox-code-play.js.
Install
npm install @ox-content/code-playimport { oxContent } from "@ox-content/vite-plugin";
import { codePlay } from "@ox-content/code-play";
export default {
plugins: [
oxContent({ highlight: true }),
codePlay({
languages: {
typescript: { execute: true, typecheck: true },
rust: true,
go: true,
},
ui: "default",
viewers: { config: true, stdio: true, stderr: true, provenance: true, timing: true },
}),
],
};Authoring
```ts play typecheck play-title="Strict TypeScript" play-strict=false play-target=ESNext
const n: number = 1;
console.log(n);
```
```rust play typecheck play-title="Release-mode Rust" play-mode=release
fn main() {
println!("ok");
}
```
```go play typecheck play-title="Go vet on"
package main
import "fmt"
func main() {
fmt.Println("ok")
}
```Use play-title, play-compact / play-headless, play-timeout=2500,
play-viewers=stdio,stderr,-timing, and play-<config-key>=... for one
sample. The MDX-style <CodePlay> tag accepts title, ui, timeout,
viewers, and config-* attributes.
<CodePlay lang="ts" title="Loose TS" typecheck ui="compact" config-strict="false">
const n = 1;
</CodePlay>Project-level examples stay opt-in per sample:
```ts play play-project=stackblitz play-file=src/main.ts play-entry=src/main.ts play-files=package.json,src/App.tsx play-project-url=https://stackblitz.com/edit/example
console.log("project");
```play-file names the current fence inside the project, play-files lists
extra files relative to the Markdown source file, and play-project-url
provides the external fallback link. Providers are metadata adapters; no
StackBlitz, CodeSandbox, or WebContainer script is loaded by Code Play.
Headless API
import { createCodePlay } from "@ox-content/code-play";
const play = createCodePlay({ languages: { typescript: true } });
const session = play.createSession({ language: "ts", code: "const n: number = 1;" });
const check = await session.typecheck();
const run = await session.run();
run.stdio;
run.stdout;
run.stderr;
run.provenance;
run.timing;run.status is ok, error, offline, timeout, cancelled, or
unsupported. Custom UIs can use the exported RunActionState helpers to
model idle, running, result, error, and offline states.
Security
play fences are trusted site content. Do not mark unreviewed or
visitor-supplied snippets as play.
- No sample is executed during Markdown transform or SSG.
- JavaScript and TypeScript run in
node:vmon Node, or in a Web Worker in the browser. Browsers without Worker support fall back to<iframe sandbox="allow-scripts">with noallow-same-origin. Snippets are never run with page-originFunction. - Published widgets hide Typecheck unless
endpoints.typecheckis set. Cancel appears while a run is in flight. - Framework previews use the same iframe flags and load runtimes from esm.sh.
- Rust and Go POST source to the official playgrounds (or your
endpoints). The Vite/__ox-code-play/*proxy is dev-only. - Other languages need a Piston-compatible
endpointyou trust. shnever spawns a local shell.- Project sandboxes include trusted source in the static payload.
play-filesare read only from relative paths inside the configured Markdown source root, with symlink real paths checked before embedding.
Example
A runnable Vite site lives in examples/code-play:
vp run --filter ./examples/code-play devThe docs site also dogfoods JavaScript, TypeScript, Rust, and Go widgets on Code Play.
See Code Play in the docs site.
