Building sections

Talking to other sections

Props, shared state, and when to use which.

Every island is its own createRoot, so React Context cannot reach between them. There are three ways across, and which one you want depends on whether you need props or state.

NeedUse
Another section's Liquid datauseSectionProps(name)
Two sections agreeing on a valueuseShared(key, initial)
A section exposing its own stateusePublish(key, value)
A designed domain — cart, overlayscreateStore

Props are already public

Every section renders its payload into the page as <script type="application/json"> — that's how a section gets its props in the first place. So any island can read any other section's data with no cooperation from it:

1const header = useSectionProps('header') // by component name
2const props = useSectionProps({ id }) // by section id
3
4if (!header) return null // a merchant may have removed it

It re-reads when the theme editor swaps that section, so an edit doesn't leave you holding a stale payload.

getSectionProps(name) is the same read outside React — an event handler, a module-level lookup. getAllSectionProps() dumps every mounted section, which is useful in the console and too blunt for render.

Always handle null. Reading another section's payload couples you to a section a merchant can remove in the editor at any time.

State is not public, and shouldn't be

You can't reach into a component and read its useState — it's private, and a hook that could would break the moment that component re-rendered or unmounted.

What a component can do is publish:

1usePublish('pdp:variant', selected) // in the product section
2const [variant] = useShared('pdp:variant') // anywhere else

The publishing component decides what's part of its contract, instead of everything it happens to hold becoming one. The value clears when the publishing component unmounts, so a reader is never left holding state belonging to a section a merchant just deleted.

Shared state without a module

For state that isn't owned by anyone in particular, useShared is useState across islands:

const [open, setOpen] = useShared('size-guide', false)

Any island using the same key sees the same value. Keys are global — prefix them with something you own (wishlist:ids, not ids).

Outside React: getShared, setShared and subscribeShared. clearShared takes a key, a prefix: to clear a group, or nothing to clear everything.

When to still use createStore

A shared domain with actions, loading and error states and one obvious owner — the cart is the example. It has addToCart, changeLine, a status, an error, and every island agrees about it. That earns a module.

useShared is for ad-hoc wiring that doesn't deserve one. Writing a store file just so two sections can agree on a boolean is ceremony.

See State across islands for why a module-level variable is enough in the first place.