State Management
Nuxt provides useState composable to create a reactive and SSR-friendly shared state across components.
useState
is an SSR-friendly ref
replacement. Its value will be preserved after server-side rendering (during client-side hydration) and shared across all components using a unique key.
Read more in Docs > Api > Composables > Use State.
Because the data inside
useState
will be serialized to JSON, it is important that it does not contain anything that cannot be serialized, such as classes, functions or symbols.Best Practices
Never define
Such state will be shared across all users visiting your website and can lead to memory leaks!
const state = ref()
outside of <script setup>
or setup()
function.Such state will be shared across all users visiting your website and can lead to memory leaks!
Instead use
const useX = () => useState('x')
Examples
Basic Usage
In this example, we use a component-local counter state. Any other component that uses useState('counter')
shares the same reactive state.
app.vue
<script setup>const counter = useState('counter', () => Math.round(Math.random() * 1000))</script><template> <div> Counter: {{ counter }} <button @click="counter++"> + </button> <button @click="counter--"> - </button> </div></template>
Read and edit a live example in Docs > Examples > Composables > Use State.
Read more in Docs > Api > Composables > Use State.
Advanced
In this example, we use a composable that detects the user's default locale from the HTTP request headers and keeps it in a locale
state.
Read and edit a live example in Docs > Examples > Other > Locale.
Shared State
By using auto-imported composables we can define global type-safe states and import them across the app.
composables/states.ts
export const useCounter = () => useState<number>('counter', () => 0)export const useColor = () => useState<string>('color', () => 'pink')
app.vue
<script setup>const color = useColor() // Same as useState('color')</script><template> <p>Current color: {{ color }}</p></template>