Skip to content
Tools— browse docs
On this page

Step 4: Design the embed

The same component renders full-size and card-sized — context.view is how it knows which.

Whoever drops your pin board into a card meets it small, next to a paragraph of prose, long before anyone opens it on its own. That inline mount is a block — the embeddable face of your tool — and you don't write a second component for it. You write one that knows which face it's wearing.

The host mounts your render in one of three views and tells you which via context.view: "embed" (block-sized, inline), "editor" (the side panel — the default), or "fullscreen". A pin board only really has two layouts — branch on "embed" and treat everything else the same:

const compact = context.view === "embed"
One board, two faces
src/tool.tsx Lines 98 to 103 highlighted.

Edit and the example re-runs. Tab indents; press Escape to leave the editor.

Running · your edits, live
Starting the example…

Flip the "pretend view" chip to embed. You should see: the header disappears, pins and empty-state text shrink, and the board still takes clicks and drags — because you also set embed: "interactive" on the definition.

Note:

Why interactive, not preview

The default (embed: "preview") mounts your embed read-only and pointer-inert, behind a click-to-open affordance — right for a document whose embed is a preview of it, like a mini- map that would otherwise swallow a card's scroll wheel. A pin board is the opposite kind of thing: dropping and dragging pins is the tool, so an inert picture would be a smaller, broken version of it, not a smaller correct one. embed: "interactive" mounts it live, with the viewer's real edit rights, plus one small corner control to open the full view.

What if I want a summary of the board somewhere else entirely?Deep dive

context.view === "embed" is for this document's own inline face — someone drops this exact board into a card. That's different from wanting, say, "boards near this one" shown in world chrome, with no document to point at.

For that you'd ship a second, small defineBlock with scope: "world": it reads the world instead of block.data, and it mounts anywhere with one line, no BlockInstance to supply — <BlockSlot type="pin-board-roster" />. It's a different shape from what this page builds; see World blocks for the whole pattern.

Recap

  • The host mounts one render in three views; context.view === "embed" is the block-sized one.
  • embed: "interactive" mounts a control surface live with real edit rights; the default, "preview", mounts a read-only picture behind a click-to-open.
  • A scope: "world" block, mounted via <BlockSlot>, is the different shape you'd reach for to summarize the board somewhere with no document of its own.

Next steps