title | description | i18nReady | type |
---|---|---|---|
Share state between Astro Components |
Learn how to share state across Astro components with Nano Stores. |
true |
recipe |
import { Steps } from '@astrojs/starlight/components'; import PackageManagerTabs from '~/components/tabs/PackageManagerTabs.astro';
:::tip Using framework components? See how to share state between Islands! :::
When building an Astro website, you may need to share state across components. Astro recommends the use of Nano Stores for shared client storage.
1. Install Nano Stores:<PackageManagerTabs>
<Fragment slot="npm">
```shell
npm install nanostores
```
</Fragment>
<Fragment slot="pnpm">
```shell
pnpm add nanostores
```
</Fragment>
<Fragment slot="yarn">
```shell
yarn add nanostores
```
</Fragment>
</PackageManagerTabs>
-
Create a store. In this example, the store tracks whether a dialog is open or not:
import { atom } from 'nanostores'; export const isOpen = atom(false);
-
Import and use the store in a
<script>
tag in the components that will share state.The following
Button
andDialog
components each use the sharedisOpen
state to control whether a particular<div>
is hidden or displayed:<button id="openDialog">Open</button> <script> import { isOpen } from '../store.js'; // Set the store to true when the button is clicked function openDialog() { isOpen.set(true); } // Add an event listener to the button document.getElementById('openDialog').addEventListener('click', openDialog); </script>
<div id="dialog" style="display: none">Hello world!</div> <script> import { isOpen } from '../store.js'; // Listen to changes in the store, and show/hide the dialog accordingly isOpen.subscribe(open => { if (open) { document.getElementById('dialog').style.display = 'block'; } else { document.getElementById('dialog').style.display = 'none'; } }) </script>