Skip to main content
A widget surfaces part of an owner’s content from your app on their cskn profile: their latest posts, a stat, a progress bar, a button. The server resolves each widget into a small declarative payload, and every surface (web, mobile, desktop, TV) renders that same payload, so a widget written once appears everywhere. The SDK covers two jobs:
  • Settings: your app’s settings screen lets the owner choose which widgets to show, where and how big.
  • Rendering: a profile page fetches the widgets a visitor may see and draws them. @cskn/ui has the renderers.

Settings screen

If you use @cskn/ui, drop in <WidgetSettings />. Otherwise useWidgetSettings gives you the same behavior to render in your own design:
WidgetDefinition[]
What your app offers, translated to locale when the catalog has a translation.
Record<string, WidgetConfig>
The owner’s unsaved choices, keyed by widget id. Widgets added since they last saved appear switched off.
'not-activated' | 'private' | 'followers-only' | null
Set when at least one widget is on but something else hides it from visitors. Supply your own wording for each.
(id, value) => void
Edit the draft. setOption(id, key, value) sets a widget-specific option.
…
Save the draft. saveError is 'not-activated' when the app is not on the owner’s profile, otherwise 'failed'.

Sizes and slots

The action slot holds buttons, not cards: only an action-layout widget may sit there, and it may sit nowhere else. slotsForLayout(layout) returns the slots to offer for a widget. A theme without a given region falls back to content, so an enabled widget is never lost.

Rendering a profile’s widgets

groupWidgetsBySlot always returns every slot key, possibly empty, and sends unknown slots to content.

Content layouts

Each WidgetInstance.content has a layout: list, grid, media, gallery, stat, text, progress, action, or custom. The custom layout carries a node tree built from a closed vocabulary (flex and grid containers; text, image, avatar, video, icon, button, badge, progress, divider, spacer leaves). There is no HTML, no style strings and no script, so the same tree is safe to render on someone else’s profile on any surface.

Lower-level API