Ahead of the release
npm install @evanion/astro-widget gives you 0.3.0. These pages document main, which has changes that release does not.
@evanion/astro-widget
Render CMS-driven Astro sections from structured widget data. Build-time only — no runtime, no hydration, nothing shipped to the browser.
---
import Widgets from '@evanion/astro-widget/components/Widgets.astro';
import { registry } from '../registry';
import page from '../data/page.json';
---
<Widgets items={page.sections} registry={registry} ctx={{ site: 'baize.example' }} />Where page.json is whatever your CMS writes:
{
"sections": [
{
"id": "header",
"type": "listing-header",
"props": { "title": "Brass: Birmingham" }
}
]
}Installation
npm install @evanion/astro-widgetAstro is a peer dependency, pinned at ^7.3.1. Node 20 or newer. ESM only.
Two entry points
import { defineWidgets, validateItems } from '@evanion/astro-widget';
import Widgets from '@evanion/astro-widget/components/Widgets.astro';The registry helper, the validator and the types come from @evanion/widget and
are re-exported here as compiled JavaScript. The component is not: an .astro module has to be compiled by Astro’s own Vite
plugin, which runs in your project rather than in this package’s build, so
Widgets.astro is published as source under /components/.
The Astro counterpart to @evanion/react-widget
The same item data, with the differences Astro forces. One array renders through either package and produces the same widgets in the same order.
| react-widget | astro-widget | |
|---|---|---|
| Page-level data | ctx prop | ctx prop, same name |
| Prop type inference | inferred from the component map | none — see below |
| Item shape | AnyWidgetItem | AnyWidgetItem, the same type |
Nested children | rendered as the component’s children | no recursion; a widget renders its own |
| Region chrome | chrome.wrapper | none |
An .astro module’s default export is an AstroComponentFactory, which carries
no prop types at all — the props of a .astro file live in its frontmatter
Props interface and are not reachable from the factory’s type. So there is
nothing to infer a widget’s props from, the way react-widget infers them from a
ComponentType. validateItems covers that ground
at build time instead, and it is the only check a widget’s props get.
Neither package has a provider. react-widget cannot have one, because React’s
react-server condition has no createContext; this one has nothing to provide
one for, because an Astro component runs once, top down, with no render-time
context to read from.
Pages
- Getting started — the registry, the data shape, chrome
- Validation — catching a bad CMS save at build time
- API reference