Handle Page State in Astro
This guide won’t cover persistent state management across page navigations. For that, you’ll want to take a look at nanostores. This guide focuses solely on state management within a page
Astro brings the wonderful world of components to static sites. But with components comes the need to share and manage state. Using a Proxy
, you can create a simple state store that can be imported into any script in the project.
Creating a State Store
Start by creating a new file called state.js
in the src
directory. This file will contain the state store. As an example, we’ll use count
as a state property.
The state
object is a Proxy
that will intercept any changes to the object in set
. listen
allows you to add event listeners to the state store. Useful for updating the UI when the state changes.
Using the State Store
Once you’ve defined a state store, you can import it in the script
tag of any .astro
file in your project. In addition, I believe this works in any UI framework file too, as long as you specify client:only
, though I haven’t tested this, as each framework has its own state management solutions.
As an example, in src/pages/index.astro
create a script tag and import the state store.
We can also import the state store in other .astro
components and use it there, and state will remain consistent across all components. For example, editing the state in src/components/counter.astro
would update the state in src/pages/index.astro
.
Typing the State Store
If you’re using TypeScript, you can type the state store and it’s values to make it easier to work with.
Use-cases
My original use-case for this was to manage the state between my navigation & sidebar components on mobile. As the button to open the sidebar was on the navigation menu, I needed a way to open the sidebar from the navigation component. Using a Proxy
like this, I’m able to listen for changes to the state of the sidebar and update the UI accordingly.
You can use this to manage the state of a modal, form, or any other UI state that has a need to exist over multiple components. Nanostores is great for managing state across page navigations, but if you need to manage state within a page, it’s a little overkill.