React context does not cross an island boundary
Composing a compound component inside a .astro file breaks the build; the assembly has to live on the React side.
IntermédiaireArticle4 steps
A compound component — accordion, popover, tabs — shares its state through React context.
Written in a .astro file, with the hydration directive on the root, it throws at build
time: the parts cannot find their root’s context.
1. See what a directive bounds
client:load does not make the page reactive: it declares one island, whose root is the
component carrying the directive. Children written in the .astro file are rendered by
Astro, at build time, outside that React tree. They therefore descend from no context
provider — there is no shared tree in which to look for one.
2. Assemble on the React side
The assembly goes into a single .tsx file: the root and its parts form one React tree
there, and that file is what carries the directive. The page now sees a single component.
3. Pass serialisable data only
An island’s props cross the boundary as JSON. An array of {label, value} objects gets
through; a render function does not. The constraint is welcome: it pushes assembly into the
React file and data into the page.
4. Refuse the island when a native element suffices
The converse rule matters just as much. A panel that opens and closes is a <details>: it
needs no script, stays in the delivered HTML, and prints expanded. A popover, by contrast,
positions itself, closes on an outside click and announces its state — three behaviours no
native element provides. You pay for a React root with a behaviour, never with uniformity.