These pages document @evanion/react-widget 0.3.3, the version on npm.
Nesting items
A widget’s children field allows you to nest items inside other widgets. For example, you can place multiple ListingCard widgets inside a single Showcase widget. @evanion/react-widget automatically renders these nested items as the parent component’s children prop.
Putting Listings Inside a Showcase
The defineItems helper used in Getting started provides deep type checking. It validates nested items with the same rigor as top-level ones, ensuring that every child item matches a known widget type and has the correct props.
const = (: { : string; ?: React. }) => (
<>
<>{.}</>
{.}
</>
);
const { , } = ({
: { : , : },
});
const = ([
{
: 'tonight',
: 'showcase',
: { : 'On the table tonight' },
: [{ : 'hive', : 'listing', : { : 'Hive' } }],
},
]);
const = (< ={} />); // -> '<section><div data-widget-id="tonight" data-widget-type="showcase"><div><h2>On the table tonight</h2><div data-widget-id="hive" data-widget-type="listing"><h3>Hive</h3></div></div></div></section>'In this example, the Showcase component declares a children prop (React.ReactNode). Because Widgets renders the nested items as children, the tonight item (a Showcase) effectively wraps the Hive listing. In the resulting HTML, the child’s chrome sits inside the parent’s chrome.
Type Safety and Nested Items
TypeScript prevents you from nesting items where they don’t belong. Since ListingCard does not declare a children prop, the compiler will reject any attempt to nest items under it.
([
{
: 'azul',
: 'listing',
: { : 'Azul' },
// @ts-expect-error ListingCard declares no children, so nothing nests under it
: [{ : 'hive', : 'listing', : { : 'Hive' } }],
},
]);Where Nested Items are Rendered
@evanion/react-widget handles the recursive rendering of items and hands the result to the parent component as its children prop. The parent component decides where these children appear.
In the Showcase component, the children are rendered under an <h2> heading. If a component declares children in its type but never renders them in its JSX, the nested items will be ignored by the browser, even though they are valid.
The limits of compile-time checks
It’s important to remember that defineItems only checks the code you write.
A CMS payload is just JSON; it never meets the TypeScript compiler. A CMS could send nested items under a ListingCard, and Widgets would simply ignore them during render. To catch these structural errors in your data, you must use validateItems at runtime. Checking a CMS payload shows how to implement this.