> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cskn.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Widget renderers

> Draw a profile's widgets: cards, grids, action buttons and custom node trees.

These components render the `WidgetInstance` payloads from [`useUserWidgets`](/sdk/widgets#rendering-a-profiles-widgets). The same payload renders identically on every surface.

```tsx theme={null}
import { useUserWidgets, groupWidgetsBySlot } from '@cskn/sdk';
import { WidgetGrid, WidgetActions } from '@cskn/ui';

function Profile({ username }: { username: string }) {
  const { data } = useUserWidgets(username);
  const slots = groupWidgetsBySlot(data?.widgets);

  return (
    <>
      <Hero />
      <WidgetGrid widgets={slots.bio} />
      <WidgetActions widgets={slots.action} />
      <WidgetGrid widgets={slots.content} />
      <WidgetGrid widgets={slots.footer} />
    </>
  );
}
```

## WidgetGrid

<ParamField path="widgets" type="WidgetInstance[]" required>The widgets to draw. Renders nothing when empty.</ParamField>

<ParamField path="columns" type="1 | 'auto'" default="1">
  `1` stacks one widget per row, which suits single-column profile pages. `'auto'` uses a responsive multi-column grid that honors each widget's size.
</ParamField>

<ParamField path="onOpen" type="(href, widget) => void">Handle navigation yourself instead of following the link, for example to route inside a shell.</ParamField>

## WidgetCard

One widget. The owner can turn off its title row (`showHeader`) and its frame (`showCard`), which is how a widget blends into a bio or an about block. Props: `widget`, `onOpen?`.

## WidgetActions

The `action` slot: buttons that sit beside Follow.

<ParamField path="widgets" type="WidgetInstance[]" required>`groupWidgetsBySlot(…).action`.</ParamField>
<ParamField path="variant / size" type="ButtonVariant / ButtonSize" default="'outline' / 'md'">Button style. Outline keeps actions from competing with Follow.</ParamField>
<ParamField path="buttonClassName" type="string">Your own button class. The buttons then render as unstyled `Pressable`s wearing it, and `variant` is ignored.</ParamField>
<ParamField path="onOpen" type="(href, widget) => void">Intercept navigation.</ParamField>

## WidgetNode

Renders a single node of the `custom` layout's tree, with `accent` resolving the widget's accent color. You only need it when composing widget content yourself; `WidgetCard` uses it internally.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.