Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/dvlkit/nuxe/llms.txt

Use this file to discover all available pages before exploring further.

useState is Nuxe’s answer to shared reactive state that works across the SSR–client boundary. Unlike a plain ref defined in a module, a useState value lives inside the Nuxe app payload — the same object that carries useAsyncData results from server to client. This means the value is serialized into the HTML by the server, restored on the client before the first render, and kept in sync across every component that calls useState with the same key.
Two components that call useState('count') receive the same Ref. Mutating it in one component is immediately visible in the other — no Pinia store or provide/inject boilerplate required.

Signature

useState<T>(key: string, init?: () => T): Ref<T>

Parameters

key
string
required
A unique string that identifies this state entry within the app payload. Must be a non-empty string — useState throws a TypeError if key is absent, empty, or not a string.
init
() => T
An optional factory function called once to produce the initial value when the key does not yet exist in the payload. Subsequent calls with the same key return the existing Ref without calling init again. useState throws if init is provided but is not a function.

Return Values

(return value)
Ref<T>
A reactive Ref backed by the app payload. Reading .value returns the current state. Writing .value updates it reactively everywhere the same key is used.

Error conditions

useState throws in three situations:
ConditionError typeMessage
key is not a non-empty stringTypeError[nuxe] [useState] key must be a non-empty string
init is provided but is not a functionError[nuxe] [useState] init must be a function
Called outside a Nuxe plugin or setup functionError[nuxe] useState() must be called inside a Nuxe plugin or setup function…

createNuxeState

Creates an initial NuxeState record (a Record<string, Ref<unknown>>) from a plain object. Each value is wrapped in a ref unless it is already a Ref.

Signature

createNuxeState(initial?: Record<string, unknown>): NuxeState

Example

import { createNuxeState } from '@dvlkit/nuxe'

const state = createNuxeState({
  theme: 'light',
  locale: 'en',
})
// state.theme is Ref<'light'>, state.locale is Ref<'en'>

clearNuxeState

Removes one or more keys from the app state payload. Accepts a single key string, an array of keys, or a predicate function. If called with no argument, every key is removed.

Signature

clearNuxeState(keys?: string | string[] | ((key: string) => boolean)): void
keys
string | string[] | ((key: string) => boolean)
  • string — remove that single key.
  • string[] — remove all listed keys.
  • (key: string) => boolean — remove every key for which the predicate returns true.
  • omitted — remove all keys.

Examples

Basic counter shared across components

<!-- Counter.vue -->
<script setup lang="ts">
import { useState } from '@dvlkit/nuxe'

const count = useState('counter', () => 0)
</script>

<template>
  <button @click="count++">Clicked {{ count }} times</button>
</template>
Any other component calling useState('counter') receives the same Ref and will react to changes.

SSR-hydrated user session

// composables/use-session.ts
import { useState } from '@dvlkit/nuxe'

interface Session {
  userId: string | null
  role: 'guest' | 'user' | 'admin'
}

export function useSession() {
  return useState<Session>('session', () => ({
    userId: null,
    role: 'guest',
  }))
}
<script setup lang="ts">
import { useSession } from '~/composables/use-session'

const session = useSession()
</script>

<template>
  <p v-if="session.userId">Welcome back, user {{ session.userId }}</p>
  <p v-else>You are not logged in.</p>
</template>

Clearing state on logout

import { clearNuxeState } from '@dvlkit/nuxe'

function logout() {
  // Clear only session-related keys
  clearNuxeState((key) => key.startsWith('session'))
}
Use clearNuxeState during logout or after a user switches accounts to prevent stale personalized data from leaking into the next session.

Build docs developers (and LLMs) love