Typed React/TSX components for Dossier. Render the same self-contained design via SSR, or use the block components live inside a React/Next app.
import { renderDossier } from "@kylebegeman/dossier-react";
const { html, embedHtml, md, digest } = await renderDossier(model); // model: DossierModelReuses the core design system, client runtime, and build-time enrichment (Shiki +
Graphviz), so the output matches the Node generator. model.meta.skin and
model.meta.theme are honored by the shared shell. CLI:
npx tsx src/cli.tsx ../examples/sample.dossier.json --theme forest --skin console-slate --embed
# -> *.react.html + *.react.embed.htmlimport { DossierDocument, setCtx } from "@kylebegeman/dossier-react";
setCtx({ glossary: new Map(), baseUrl: "" }); // resolves [[Term]] / [[slug]] in text
<DossierDocument model={model} animate /> // whole document; Motion entrance on scroll when hydratedOr render a single block with <Block b={model.blocks[0]} />. Import the core stylesheet
(src/theme/tokens.css.mjs exports the CSS string) once at your app root for the
ds- classes.
DossierDocument animate uses Motion and is meant for hydrated
usage; it honors prefers-reduced-motion. For a static, no-JS file, use renderDossier()
or the Node generator.
The static artifact needs no client framework, its interactivity is a small vanilla runtime, so the generated HTML works with zero JS dependencies. When you mount these components live (hydrated) in a React app, that's the right place to layer richer interaction libraries:
- Motion, wrap blocks in
motion.*withinitial={false}so SSR output stays correct and hydration adds entrance/gesture animation. - Base UI, swap the native
<details>/dialog affordances for fully accessible overlays when you need them.
These are intentionally not baked into the static generator, where they would add no runtime benefit (there is no client React at view time).
| Export | Description |
|---|---|
renderDossier(model, { theme, skin }) |
SSR -> { html, embedHtml, md, digest } (self-contained full and embed files). |
DossierDocument |
Live document component; animate adds a Motion scroll entrance (hydrated). |
Block |
Component dispatcher over all built-in block types. |
registerComponent(type, Comp) |
Register a React component for a custom block type, plugin parity with the Node generator's registerBlock. Unregistered-but-known types fall back to the Node string renderer. |
setCtx({ glossary, baseUrl }) |
Inline-markdown resolution context (call before rendering). |
DossierModel, BlockModel, ReviewCandidate, … |
Types. |