Skip to content

Widget State

A widget instance carries its own content props plus Capell runtime metadata. This page covers the two instance-state layers, how presentation settings resolve, and how to choose a loading strategy.

Widget instance data has two layers:

LayerPurposePublic component receives it?
data.*The widget’s own content propsYes
data.__capell.*Capell runtime, presentation, and interaction metadataNo

For example:

[
'type' => 'video-player',
'data' => [
'title' => 'Product walkthrough',
'video_url' => 'https://example.com/video.mp4',
'__capell' => [
'presentation' => [
'loading_strategy' => 'visible',
],
'interactions' => [
[
'label' => 'Open transcript',
'target_type' => 'widget',
'behavior' => 'modal',
'target_widget' => [
['type' => 'content', 'data' => ['content' => '<p>Transcript...</p>']],
],
],
],
],
],
]

The public renderer strips data.__capell before passing props to the widget component. A video widget can receive title and video_url; it must not receive its presentation settings, nested target widgets, editor metadata, or interaction internals.

Widget definitions can provide type defaults through defaultPresentationSettings. Editors can override those settings on one widget instance under data.__capell.presentation.

Resolution order is:

  1. instance override in data.__capell.presentation;
  2. widget definition default;
  3. presentation preset default;
  4. system default.

The system default keeps existing content server-rendered. Only opt a widget or block into lazy behaviour when it should genuinely wait for visibility, idle time, or visitor interaction.

Loading strategyUse when
eagerThe widget is visible and needed for the first render.
visibleThe widget can wait until it enters the viewport.
interactionThe widget is only needed after a click, focus, or similar action.
idleThe widget is useful soon, but not critical to initial rendering.

For interaction targets, prefer interaction resources unless the target also appears server-rendered elsewhere on the page.