Shared State (Pinia)¶
Each Vue island is its own app, but they can share reactive state through a single page-wide Pinia instance. This is opt-in by design: Pinia loads only when a component imports a store. The island bootstrap then installs that shared instance on the islands β but a page where no component uses a store ships no Pinia at all.
A store module activates the shared instance on import (via ensureSharedPinia()), and because every store resolves against the same active Pinia, any islands that import it share state. Native ESM, pay-per-use.
Requirement: stores import
pinia, so the theme must expose it inexposeNpmPackages(see JS Configuration). If a store is imported without Pinia exposed, the build fails loudly.
Authoring a shared store¶
Call ensureSharedPinia() at the top of your store module, then define stores as usual:
Two different islands β say a header cart button and a cart drawer β that both import { useUiStore } now read and write the same state.
The customer-data bridge¶
useCustomerData is a ready-made store that mirrors Magento's private content (the customer-data sections: cart, customer, wishlist, compare-products, β¦) into reactive state:
It is read-mostly: Magento's native customer-data.js stays the owner of the canonical store (localStorage['mage-cache-storage']) and the /customer/section/load/ endpoint. The bridge reads that cache, re-syncs when Magento broadcasts an update, and exposes reload() for an explicit refresh β so it never breaks Full Page Cache.
| Member | Purpose |
|---|---|
sections |
Reactive map of all sections. |
section(name) |
A single section, or null. |
sync() |
Re-read the canonical store (called automatically on Magento updates). |
reload(names = [], { force }) |
Fetch sections from /customer/section/load/ and merge. |
How it stays FPC-safe¶
Magento serves cached pages and loads private content client-side after render (via /customer/section/load/, a never-cached endpoint), so per-user data is never baked into the cached HTML. The bridge observes that flow instead of fighting it: it reads mage-cache-storage, subscribes to Magento's update broadcasts, and only the explicit reload() ever hits the network.
Next Steps¶
- JS Configuration β exposing npm packages like
piniato the bundle. - Vue Islands β the per-island app model this state layer spans.