The Reactive Transfer State integration uses nanostores
to bring up reactivity to the @astro-tools/transfer-state
library.
This way, you can subscribe to store changes and follow the Astro recommendations for sharing state with the improvement of having isolated state between requests and transferred state from server to client, with Astro and any UI framework.
For setting up the reactive state management with request isolation and transfer state, include the integration in your Astro project:
- Install the library and its dependencies using your preferred package manager:
npm i -D astro-integration-kit @astro-tools/transfer-state @astro-tools/reactive-transfer-state
- Add the integration to your project configuration:
astro.config.mjs import { defineConfig } from 'astro/config';import { reactiveTransferState } from '@astro-tools/reactive-transfer-state';export default defineConfig({integrations: [reactiveTransferState()],});
Use withTransferState
from the virtual module @astro-tools:reactive-transfer-state
with any ReadableAtom
from nanostores
library to create a store. This store will be transferred from the server to the client and will be isolated by request:
import { atom } from 'nanostores';
export const myStore = withTransferState('key', atom('initial value'));
Then use the store in any Astro or UI framework component.
For example, the Example.svelte
is rendered in server-side using the uuid
nanostore. The hydration process keeps the value as it comes from server:
---import ExampleComponent from './Example.svelte';import { uuidStore } from './uuid-store';
interface Props { id: string;}
const { id } = Astro.props;
uuidStore.set('fc379108-c24e-47f5-b119-45db86e0e94a');---<button id="trigger">Click me to hydrate!</button><hr /><ExampleComponent {id} client:on="click #trigger" />
<script lang="ts">import { onMount } from 'svelte';
import Output from '@/libs/examples/Output.svelte';import { notifyHydration } from '@/libs/examples/hydration';
import { uuidStore } from './uuid-store';
export let id: string;
let hydrated = false;
onMount(() => { hydrated = true; notifyHydration(id);});</script>
<Output hydrated={hydrated} text={$uuidStore || 'UUID not defined'} />
import { atom } from 'nanostores';
import { withTransferState } from '@astro-tools:reactive-transfer-state';
export const uuidStore = withTransferState('uuid', atom<string | null>(null));
<script lang="ts">export let text: string;export let hydrated = false;</script>
<div class="output" class:output--hydrated={hydrated}>{text}</div>
<style lang="scss"> @use './Output.scss';</style>