On this page
Share State Between Islands
When building an Astro website with islands architecture / partial hydration, you may have run into this problem: I want to share state between my components.
UI frameworks like React or Vue may encourage “context” providers for other components to consume. But when partially hydrating components within Astro or Markdown, you can’t use these context wrappers.
Astro recommends a different solution for shared client-side storage: Nano Stores.
Why Nano Stores?
The Nano Stores library allows you to author stores that any component can interact with. We recommend Nano Stores because:
- They’re lightweight. Nano Stores ship the bare minimum JS you’ll need (less than 1 KB) with zero dependencies.
- They’re framework-agnostic. This means sharing state between frameworks will be seamless! Astro is built on flexibility, so we love solutions that offer a similar developer experience no matter your preference.
Still, there are a number of alternatives you can explore. These include:
- Svelte’s built-in stores
- Solid signals outside of a component context
- Vue’s reactivity API
- Sending custom browser events between components
Installing Nano Stores
To get started, install Nano Stores alongside their helper package for your favorite UI framework:
You can jump into the Nano Stores usage guide from here, or follow along with our example below!
Usage example - ecommerce cart flyout
Let’s say we’re building a simple ecommerce interface with three interactive elements:
- An “add to cart” submission form
- A cart flyout to display those added items
- A cart flyout toggle
Try the completed example on your machine or online via Stackblitz.
Your base Astro file may look like this:
Using “atoms”
Let’s start by opening our CartFlyout
whenever CartFlyoutToggle
is clicked.
First, create a new JS or TS file to contain our store. We’ll use an “atom” for this:
Now, we can import this store into any file that needs to read or write. We’ll start by wiring up our CartFlyoutToggle
:
Then, we can read isCartOpen
from our CartFlyout
component:
Using “maps”
Now, let’s keep track of the items inside your cart. To avoid duplicates and keep track of “quantity,” we can store your cart as an object with the item’s ID as a key. We’ll use a Map for this.
Let’s add a cartItem
store to our cartStore.js
from earlier. You can also switch to a TypeScript file to define the shape if you’re so inclined.
Now, let’s export an addCartItem
helper for our components to use.
- If that item doesn’t exist in your cart, add the item with a starting quantity of 1.
- If that item does already exist, bump the quantity by 1.
With our store in place, we can call this function inside our AddToCartForm
whenever that form is submitted. We’ll also open the cart flyout so you can see a full cart summary.
Finally, we’ll render those cart items inside our CartFlyout
:
Now, you should have a fully interactive ecommerce example with the smallest JS bundle in the galaxy 🚀
Try the completed example on your machine or online via Stackblitz!
More recipes
-
Share State Between Islands
Learn how to share state across framework components with Nano Stores.
-
Add an RSS feed
Add an RSS feed to your Astro site to let users subscribe to your content.
-
Installing a Vite or Rollup plugin
Learn how you can import YAML data by adding a Rollup plugin to your project.
-
Build Forms With API Routes
Learn how to use JavaScript to send form submissions to an API Route
-
Build HTML Forms in Astro Pages
Learn how to build HTML forms and handle submissions in your frontmatter
-
Use Bun with Astro
Learn how to use Bun with your Astro site.
-
Call endpoints from the server
Learn how to call endpoints from the server in Astro.
-
Verify a Captcha
Learn how to create an API route and fetch it from the client.
-
Build your Astro Site with Docker
Learn how to build your Astro site using Docker.
-
Add icons to external links
Learn how to install a rehype plugin to add icons to external links in your Markdown files
-
Add i18n features
Use dynamic routing and content collections to add internationalization support to your Astro site.
-
Add Last Modified Time
Build a remark plugin to add the last modified time to your Markdown and MDX.
-
Add Reading Time
Build a remark plugin to add reading time to your Markdown or MDX files.
-
Share State Between Astro Components
Learn how to share state across Astro components with Nano Stores.
© 2021 Fred K. Schott
Licensed under the MIT License.
https://docs.astro.build/en/core-concepts/sharing-state/