Components

Import these from @opentf/web-docs and use them inline in any .mdx page.

Callout

Admonition box. type is note, tip, info, warning, or danger; title is optional and defaults to the type.

MDX
import { Callout } from "@opentf/web-docs";

<Callout type="warning" title="Heads up">
  APIs may change while OTF Web is in pre-release.
</Callout>
Note
A neutral note.
Tip
Pass a bare expression to $derived(a + b).
Experimental
Pre-release APIs may change.
Avoid
Don't mutate state outside a signal.

Steps

Numbered walkthrough. Each child heading becomes a numbered step, so it composes with plain Markdown.

MDX
import { Steps } from "@opentf/web-docs";

<Steps>
### Install
Run `bun add @opentf/web`.

### Start the dev server
Run `bun run dev`.
</Steps>

Install

Run bun add @opentf/web.

Start the dev server

Run bun run dev and open the printed URL.

Tabs

Switchable panels — handy for package-manager variants (npm / pnpm / bun) or any alternative content. Pass tabs as an array of { label, content }. content is rendered as-is: a string is plain text, a node is the node. For a code panel with a copy button, pass a CodeBlock.

JSX
import { Tabs, CodeBlock } from "@opentf/web-docs";

<Tabs tabs={[
  { label: "bun", content: <CodeBlock code="bun add @opentf/web" /> },
  { label: "npm", content: <CodeBlock code="npm i @opentf/web" /> },
]} />

Rendered:

bun add @opentf/web
npm i @opentf/web
pnpm add @opentf/web

CodeBlock

A code block for dynamic, runtime code — source you hold as a JavaScript value rather than a literal Markdown fence. Reach for it where a fence can't go: as the content of a Tabs panel, or any value built at runtime. It renders the same header-and-copy-button chrome as a fence. Props: code (the source, required), and optional lang (a language chip) and name (a filename shown in the header).

JSX
import { CodeBlock } from "@opentf/web-docs";

<CodeBlock lang="bash" name="terminal" code="bun add @opentf/web" />

Rendered:

bashterminal
bun add @opentf/web
No syntax highlighting yet

CodeBlock renders its code as plain (unhighlighted) text. Highlighting happens at build time in the compiler, which only sees literal Markdown fences — not a runtime string prop. Runtime highlighting for CodeBlock is deferred to future work. Prefer a fenced code block when the code is static; use CodeBlock only when it must be a value (e.g. a tab panel).

Fenced code blocks get copy buttons for free

A plain Markdown fence in a docs page is highlighted at build time and decorated with a copy button at runtime — no component needed.