Persistent State Management
with Nanostores in Astro

Maintaining state across page reloads and browser sessions

Introduction to Persistent State

Persistent state management is crucial for maintaining user data across page reloads or even browser sessions. In Astro projects, we can achieve this using @nanostores/persistent, an extension of Nanostores that leverages browser storage mechanisms.

This approach is particularly useful for storing user preferences, authentication tokens, or any data that should survive page refreshes.

Setting Up Persistent Store

Let's look at how to set up a persistent counter using @nanostores/persistent:

import { persistentAtom } from '@nanostores/persistent'

export const $persistentCounter = persistentAtom('persistentCounter', 0, {
	encode: JSON.stringify,
	decode: JSON.parse
})

export function incrementPersistent() {
	$persistentCounter.set($persistentCounter.get() + 1)
}

export function decrementPersistent() {
	$persistentCounter.set($persistentCounter.get() - 1)
}

export function resetPersistent() {
	$persistentCounter.set(0)
}
---
import { $persistentCounter } from '../stores/persistentCounterStore'
---

<div>
	<button id="dec">-</button>
	<span>{$persistentCounter.get()}</span>
	<button id="inc">+</button>
	<button id="reset">Reset</button>
</div>

<script>
	import { $persistentCounter, incrementPersistent, decrementPersistent, resetPersistent } from '../stores/persistentCounterStore'

	document.getElementById('dec')?.addEventListener('click', decrementPersistent)
	document.getElementById('inc')?.addEventListener('click', incrementPersistent)
	document.getElementById('reset')?.addEventListener('click', resetPersistent)

	$persistentCounter.subscribe(value => {
		document.querySelector('span').textContent = value
	})
</script>
<script>
import { $persistentCounter, incrementPersistent, decrementPersistent, resetPersistent } from '../stores/persistentCounterStore'
</script>

<div>
	<button onclick={decrementPersistent}>-</button>
	<span>{$persistentCounter}</span>
	<button onclick={incrementPersistent}>+</button>
	<button onclick={resetPersistent}>Reset</button>
</div>
import { useStore } from '@nanostores/react'
import { $persistentCounter, incrementPersistent, decrementPersistent, resetPersistent } from '../stores/persistentCounterStore'

export function PersistentCounter() {
	const count = useStore($persistentCounter)

	return (
		<div>
			<button onClick={decrementPersistent}>-</button>
			<span>{count}</span>
			<button onClick={incrementPersistent}>+</button>
			<button onClick={resetPersistent}>Reset</button>
		</div>
	)
}
<template>
	<div>
		<button @click="decrementPersistent">-</button>
		<span>{{ count }}</span>
		<button @click="incrementPersistent">+</button>
		<button @click="resetPersistent">Reset</button>
	</div>
</template>

<script setup>
import { useStore } from '@nanostores/vue'
import { $persistentCounter, incrementPersistent, decrementPersistent, resetPersistent } from '../stores/persistentCounterStore'

const count = useStore($persistentCounter)
</script>

Key Features of Persistent State

  • State persists across page reloads
  • Can use different storage mechanisms (localStorage, sessionStorage)
  • Seamless integration with existing Nanostores setup
  • Type-safe with TypeScript support

Best Practices and Considerations

  • Use persistent state for non-sensitive data only
  • Consider data expiration and cleanup strategies
  • Be mindful of storage limits in browsers
  • Provide fallback mechanisms for users with storage restrictions

Thank You!

Thank you for exploring this demonstration of state management using Nanostores in Astro! I hope you found this example illuminating and enjoyed seeing how seamlessly different frameworks can work together when sharing state.

Remember, this is just the tip of the iceberg when it comes to state management in multi-framework Astro projects. I encourage you to experiment further, try out different scenarios, and see how Nanostores can simplify your state management needs.

If you have any questions or want to dive deeper into any aspect of this demo, don't hesitate to reach out or explore the accompanying article and source code.

Happy coding!

PS: This site showcases all three parts of the series — independent state, shared state, and persistent state management. Explore the demos and check the source code for real-world patterns you can use in your own projects!

I'm persistent

0