2022-10-06 09:15:30 +00:00
---
navigation.icon: uil:database
2023-03-19 17:42:02 +00:00
description: Nuxt provides powerful state management libraries and the useState composable to create a reactive and SSR-friendly shared state.
2022-10-06 09:15:30 +00:00
---
2022-04-06 05:56:08 +00:00
# State Management
2021-10-11 17:48:03 +00:00
2023-03-19 17:42:02 +00:00
Nuxt provides the `useState` composable to create a reactive and SSR-friendly shared state across components.
2021-10-11 17:48:03 +00:00
2022-02-07 10:16:45 +00:00
`useState` is an SSR-friendly [`ref` ](https://vuejs.org/api/reactivity-core.html#ref ) replacement. Its value will be preserved after server-side rendering (during client-side hydration) and shared across all components using a unique key.
2021-10-11 17:48:03 +00:00
2022-11-16 10:04:28 +00:00
::ReadMore{link="/docs/api/composables/use-state"}
2022-04-06 05:56:08 +00:00
::
2021-10-11 17:48:03 +00:00
2021-11-15 10:30:38 +00:00
::alert{icon=👉}
2022-02-07 10:16:45 +00:00
`useState` only works during `setup` or [`Lifecycle Hooks` ](https://vuejs.org/api/composition-api-lifecycle.html#composition-api-lifecycle-hooks ).
2021-11-16 16:12:36 +00:00
::
2022-07-21 08:56:01 +00:00
::alert{type=warning}
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.
::
2021-11-16 16:12:36 +00:00
2022-08-13 07:27:04 +00:00
## Best Practices
2021-11-16 16:12:36 +00:00
::alert{type=danger icon=🚨}
Never define `const state = ref()` outside of `<script setup>` or `setup()` function.< br >
Such state will be shared across all users visiting your website and can lead to memory leaks!
::
::alert{type=success icon=✅}
Instead use `const useX = () => useState('x')`
2021-11-15 10:30:38 +00:00
::
2021-11-16 15:37:36 +00:00
## Examples
2021-10-11 17:48:03 +00:00
2022-08-13 07:27:04 +00:00
### Basic Usage
2021-11-15 20:41:05 +00:00
2021-11-16 15:37:36 +00:00
In this example, we use a component-local counter state. Any other component that uses `useState('counter')` shares the same reactive state.
2021-10-11 17:48:03 +00:00
2021-11-15 20:41:05 +00:00
```vue [app.vue]
< script setup >
2021-11-16 15:37:36 +00:00
const counter = useState('counter', () => Math.round(Math.random() * 1000))
2021-11-15 20:41:05 +00:00
< / script >
2021-10-11 17:48:03 +00:00
2021-11-15 20:41:05 +00:00
< template >
2021-11-16 15:37:36 +00:00
< div >
Counter: {{ counter }}
< button @click =" counter ++" >
+
< / button >
< button @click =" counter-- " >
-
< / button >
< / div >
2021-11-15 20:41:05 +00:00
< / template >
2021-11-16 13:17:52 +00:00
```
2022-11-16 10:04:28 +00:00
::LinkExample{link="/docs/examples/composables/use-state"}
2022-10-25 09:33:09 +00:00
::
2021-11-15 20:41:05 +00:00
2022-11-16 10:04:28 +00:00
::ReadMore{link="/docs/api/composables/use-state"}
2022-04-06 05:56:08 +00:00
::
2023-06-09 21:22:21 +00:00
::alert{icon=📘}
To globally invalidate cached state, see [`clearNuxtState` ](/docs/api/utils/clear-nuxt-state ).
::
2023-05-20 22:31:22 +00:00
### Advanced Usage
2021-11-16 15:37:36 +00:00
2021-11-21 12:31:44 +00:00
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.
2021-11-16 13:17:52 +00:00
2023-05-20 22:31:22 +00:00
```ts [composables/locale.ts]
import type { Ref } from 'vue'
export const useLocale = () => useState< string > ('locale', () => useDefaultLocale().value)
export const useDefaultLocale = (fallback = 'en-US') => {
const locale = ref(fallback)
if (process.server) {
const reqLocale = useRequestHeaders()['accept-language']?.split(',')[0]
if (reqLocale) {
locale.value = reqLocale
}
} else if (process.client) {
const navLang = navigator.language
if (navLang) {
locale.value = navLang
}
}
return locale
}
export const useLocales = () => {
const locale = useLocale()
const locales = ref([
'en-US',
'en-GB',
...
'ja-JP-u-ca-japanese'
])
if (!locales.value.includes(locale.value)) {
locales.value.unshift(locale.value)
}
return locales
}
export const useLocaleDate = (date: Ref< Date > | Date, locale = useLocale()) => {
return computed(() => new Intl.DateTimeFormat(locale.value, { dateStyle: 'full' }).format(unref(date)))
}
```
```vue [app.vue]
< script setup >
const locales = useLocales()
const locale = useLocale()
const date = useLocaleDate(new Date('2016-10-26'))
< / script >
< template >
< div >
< h1 > Nuxt birthday< / h1 >
< p > {{ date }}< / p >
< label for = "locale-chooser" > Preview a different locale< / label >
< select id = "locale-chooser" v-model = "locale" >
< option v-for = "locale of locales" :key = "locale" :value = "locale" >
{{ locale }}
< / option >
< / select >
< / div >
< / template >
```
2022-11-16 10:04:28 +00:00
::LinkExample{link="/docs/examples/other/locale"}
2022-10-25 09:33:09 +00:00
::
2021-10-11 17:48:03 +00:00
2022-08-13 07:27:04 +00:00
## Shared State
2021-11-16 15:37:36 +00:00
2022-11-16 10:04:28 +00:00
By using [auto-imported composables ](/docs/guide/directory-structure/composables ) we can define global type-safe states and import them across the app.
2021-11-16 13:17:52 +00:00
2021-11-16 15:37:36 +00:00
```ts [composables/states.ts]
export const useCounter = () => useState< number > ('counter', () => 0)
export const useColor = () => useState< string > ('color', () => 'pink')
```
2021-11-16 13:17:52 +00:00
```vue [app.vue]
< script setup >
2021-11-16 15:37:36 +00:00
const color = useColor() // Same as useState('color')
2021-11-16 13:17:52 +00:00
< / script >
< template >
2021-11-16 16:12:36 +00:00
< p > Current color: {{ color }}< / p >
2021-11-16 13:17:52 +00:00
< / template >
```
2023-03-19 17:42:02 +00:00
## Using third-party libraries
Nuxt **used to rely** on the Vuex library to provide global state management. If you are migrating from Nuxt 2, please head to [the migration guide ](/docs/migration/configuration#vuex ).
Nuxt is not opiniated about state management, so feel free to choose the right solution for your needs. There are multiple integrations with the most popular state management libraries, including:
- [Pinia ](/modules/pinia ) - the official Vue recommendation
- [Harlem ](/modules/harlem ) - immutable global state management
- [XState ](/modules/xstate ) - state machine approach with tools for visualising and testing your state logic