@juo/blocks. Operators configure blocks without writing code — they select blocks from a library, place them onto pages, fill in props through generated forms, and translate copy, all against the same definitions a developer writes once with defineBlock.
This page covers how a portal integrates with the Editor and what that integration unlocks for the operator. For the step-by-step wiring, see Building a custom portal.
What the operator gets
A portal that opts into Editor support gives its operators:- A block picker with every block the portal registers, grouped by 1st party, 3rd party, and store-owned (see Blocks → Block groups).
- Auto-generated forms for each block’s props, driven by the block’s schema — no separate admin UI to maintain.
- Slot composition — nest blocks inside other blocks’ slots directly on the canvas.
- Presets — curated starting points an author defines on a block, shown as previews in the picker.
- Theming and translations managed alongside content, without redeploying the portal.
- Live preview — every change the operator makes renders against the real portal with real services.
How the integration works
The Editor communicates with the portal through a small protocol. Two pieces in@juo/blocks make a portal Editor-aware:
- The editor build of the web components.
@juo/blocks/web-components/editorreplaces the standard versions of<juo-context-root>,<juo-page>,<juo-extension-root>,<juo-block>, and<juo-text>with variants that connect selection, inline text editing, and drag handles. The runtime build (@juo/blocks/web-components/runtime) is the lean storefront version with none of that. See Web components for what each element does. setupEditorModefrom@juo/blocks/editor— a single call that hands the Editor the portal’s block registrations, its routes, and a bridge for theme and translation updates. Call it once from the portal entry and the rest of the integration follows.
defineBlock works in both. The differences are at the edges: <juo-text> is editable in the Editor and read-only at runtime, blocks render inside a selection wrapper in the Editor, and previewed presets arrive through the bridge.
If a block needs to react to those previews specifically — for instance, to render a hovered preset without committing — it can opt in with useBridge from its framework adapter. See Building a custom portal for the pattern.