--- title: 'State Management' description: Nuxt provides powerful state management libraries and the useState composable to create a reactive and SSR-friendly shared state. navigation.icon: i-ph-database-duotone --- Nuxt provides the [`useState`](/docs/api/composables/use-state) composable to create a reactive and SSR-friendly shared state across components. [`useState`](/docs/api/composables/use-state) 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. ::callout Because the data inside [`useState`](/docs/api/composables/use-state) will be serialized to JSON, it is important that it does not contain anything that cannot be serialized, such as classes, functions or symbols. :: ::read-more{to="/docs/api/composables/use-state"} Read more about `useState` composable. :: ## Best Practices ::callout{color="amber" icon="i-ph-warning-duotone"} Never define `const state = ref()` outside of ` ``` :link-example{to="/docs/examples/features/state-management"} ::callout To globally invalidate cached state, see [`clearNuxtState`](/docs/api/utils/clear-nuxt-state) util. :: ### Advanced Usage 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. ::code-group ```ts [composables/locale.ts] import type { Ref } from 'vue' export const useLocale = () => { return useState('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, locale = useLocale()) => { return computed(() => new Intl.DateTimeFormat(locale.value, { dateStyle: 'full' }).format(unref(date))) } ``` ```vue [app.vue] ``` :: :link-example{to="/docs/examples/advanced/locale"} ## Shared State By using [auto-imported composables](/docs/guide/directory-structure/composables) we can define global type-safe states and import them across the app. ```ts [composables/states.ts] export const useCounter = () => useState('counter', () => 0) export const useColor = () => useState('color', () => 'pink') ``` ```vue [app.vue] ``` ## 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 opinionated 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 visualizing and testing your state logic