Tutorials

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.

Act

Dark themePin the site's appearancesetTheme({theme:"dark"})
Light themePin the site's appearancesetTheme({theme:"light"})
System themeFollow the system preference againsetTheme({theme:"system"})
Switch the site to FrenchFrançaissetLocale({locale:"fr"})
Labs — ProductFilter Labs by typefilterLabs({type:"Produit"})
Labs — PrototypeFilter Labs by typefilterLabs({type:"Prototype"})
Labs — ResearchFilter Labs by typefilterLabs({type:"Recherche"})
Labs — Reset filtersClear every Labs filterfilterLabs({reset:true})
Journal — EngineeringFilter the Journal by categoryfilterJournal({category:"Ingénierie"})
Journal — SecurityFilter the Journal by categoryfilterJournal({category:"Sécurité"})
Journal — Agent-NativeFilter the Journal by categoryfilterJournal({category:"Agent-Native"})
Journal — StudioFilter the Journal by categoryfilterJournal({category:"Studio"})
Journal — Reset filtersClear every Journal filterfilterJournal({reset:true})
Tutorials — BeginnerFilter tutorials by levelfilterTutorials({level:"Débutant"})
Tutorials — IntermediateFilter tutorials by levelfilterTutorials({level:"Intermédiaire"})
Tutorials — AdvancedFilter tutorials by levelfilterTutorials({level:"Avancé"})
Tutorials — Reset filtersClear every tutorials filterfilterTutorials({reset:true})

Services

DiscoveryFrame the product before the first line of code, so the budget builds instead of correcting.openService({service:"discovery"})
Product designAn interface that holds together, carried by a design system your developers can keep alive without us.openService({service:"design"})
Web developmentA fast web application that holds up over time, with the tests and delivery chain to match.openService({service:"web"})
Mobile developmentAn iOS and Android app from a single codebase, published on both stores.openService({service:"mobile"})
Infrastructure & securityInfrastructure described as code, and Zero Trust access that does not rest on a text message.openService({service:"infrastructure"})
Maintenance & evolutionA product kept current, watched and fixed, with someone who answers when it breaks.openService({service:"maintenance"})
Agent-Native Architecture AdvisoryMake an existing product agent-operable without rewriting it — and without opening more than it should.openService({service:"agent-native"})

Go to

YorroProduct engineering studio in Abidjan and Paris. We design, we build, we ship.navigate({page:"home"})
ServicesBuild a product end to end, or advise a team on its agent-native architecture.navigate({page:"services"})
LabsWhat the studio has built: products, prototypes and research, with where each one actually stands.navigate({page:"labs"})
TutorialsStep-by-step guides drawn from real projects, grouped into tracks by topic.navigate({page:"tutorials"})
JournalThe studio's notes and positions.navigate({page:"journal"})
ContactDescribe your project; you get a framing back, not a boilerplate quote.navigate({page:"contact"})
AboutWho runs the studio, how it works, and what it turns down.navigate({page:"about"})
↑↓ move↵ runesc closeOne Actions layer