Code components - Workbench component mocks
Workbench component mocks let you preview the same component with multiple named prop and slot configurations.
You can author component mocks in a JSON file. Each mock entry becomes a tab in the Workbench preview panel.
Workbench also includes a built-in Default preview for every component. It
shows the component as Canvas renders it initially, before a content editor
populates props or slots. Canvas and Workbench generate this preview from the
first example value of each prop in component.yml and leave slots empty.
File naming and placement
Section titled “File naming and placement”Author the mock file in the same directory as the component metadata and source
file. Name it either mocks.json or [component-name].mocks.json, depending
on how the component metadata is named.
Example: index-style component
src/components/hero/ index.tsx component.yml mocks.jsonExample: named component
src/components/ card.tsx card.component.yml card.mocks.jsonMock entries
Section titled “Mock entries”Each mock file contains a JSON array of entries. Every entry includes name,
which Workbench uses as the preview tab label.
Each entry becomes its own preview tab in Workbench.
Props format
Section titled “Props format”Use the props format when the preview only changes the component props.
| Key | Description |
|---|---|
name | Labels the preview tab in Workbench. |
props | Provides prop values for the component. |
Example: heading.mocks.json
[ { "name": "Centered", "props": { "text": "Publish AI-assisted content with editorial control", "eyebrow": "Build faster", "textAlign": "center" } }]Props and slots format
Section titled “Props and slots format”Use the props and slots format when the preview needs component props and slots.
| Key | Description |
|---|---|
name | Labels the preview tab in Workbench. |
props | Provides prop values for the inferred root component. |
slots | Maps root component slots to element IDs from elements. Those IDs are arbitrary. |
elements | Defines authored child elements, keyed by arbitrary element IDs referenced from slots. |
Each entry in elements must include a type. It can also include props
and slots, which reference other element IDs from the same elements
object.
Each element type must match a discovered component name, such as card or
js.card. Workbench discovers these component types from the code components
available in your project.
Example: card.mocks.json
[ { "name": "Featured", "props": { "featured": true }, "slots": { "header": ["card-featured-header"], "content": ["card-featured-content"], "footer": ["card-featured-actions"] }, "elements": { "card-featured-header": { "type": "heading", "props": { "text": "Featured article" } }, "card-featured-content": { "type": "text", "props": { "content": "Learn how editorial teams use Canvas to review, refine, and publish AI-assisted content." } }, "card-featured-actions": { "type": "button-group", "props": { "stacked": false }, "slots": { "items": ["card-featured-primary-action", "card-featured-secondary-action"] } }, "card-featured-primary-action": { "type": "button", "props": { "label": "Get started", "href": "/sign-up", "variant": "primary" } }, "card-featured-secondary-action": { "type": "button", "props": { "label": "Read more", "href": "/articles/canvas-workflows" } } } },]Advanced format
Section titled “Advanced format”Use the advanced format when the preview needs full control over the rendered root element.
This format is useful when you need to render a component inside other components to verify how it behaves in context.
| Key | Description |
|---|---|
name | Labels the preview tab in Workbench. |
root | Identifies the root element to render. |
elements | Defines the full element tree, including the root element and any elements referenced by slots. |
Unlike the props and slots format, this version lets you control the rendered
root directly. Define that root element inside elements, along with its
props, slots, and any nested elements it references.
Each element type must match a discovered component name, such as card or
js.card. Workbench discovers these component types from the code components
available in your project.
Example: card.mocks.json
[ { "name": "In grid", "root": "card-grid", "elements": { "card-grid": { "type": "grid", "props": { "columns": 3, "gap": "md" }, "slots": { "items": ["card-1", "card-2", "card-3"] } }, "card-1": { "type": "card", "props": { "featured": true }, "slots": { "header": ["card-1-header"], "content": ["card-1-content"], "footer": ["card-1-footer"] } }, "card-1-header": { "type": "heading", "props": { "text": "Featured article" } }, "card-1-content": { "type": "text", "props": { "content": "Learn how editorial teams use Canvas to review, refine, and publish AI-assisted content." } }, "card-1-footer": { "type": "button-group", "slots": { "items": ["card-1-primary-action", "card-1-secondary-action"] } }, "card-1-primary-action": { "type": "button", "props": { "label": "Read more", "href": "/articles/canvas-workflows" } }, "card-1-secondary-action": { "type": "button", "props": { "label": "Save for later", "href": "/saved" } }, "card-2": { "type": "card", "props": { "featured": false }, "slots": { "header": ["card-2-header"], "content": ["card-2-content"], "footer": ["card-2-footer"] } }, "card-2-header": { "type": "heading", "props": { "text": "Documentation update" } }, "card-2-content": { "type": "text", "props": { "content": "Review the latest guidance for authoring Workbench component mocks." } }, "card-2-footer": { "type": "button", "props": { "label": "Open docs", "href": "/docs/workbench-mocks" } }, "card-3": { "type": "card", "props": { "featured": false }, "slots": { "header": ["card-3-header"], "content": ["card-3-content"], "footer": ["card-3-footer"] } }, "card-3-header": { "type": "heading", "props": { "text": "Team workflow" } }, "card-3-content": { "type": "text", "props": { "content": "Coordinate AI drafting, editorial review, and publishing approvals in one place." } }, "card-3-footer": { "type": "button", "props": { "label": "See workflow", "href": "/workflow" } } } }]Choosing a format
Section titled “Choosing a format”- Use the props format for quick component variations driven only by props.
- Use the props and slots format when you need slots, too.
- Use the advanced format when you need to render the component inside a different root.