Skip to content

Pinia Plugin ​

File Information ​

  • Path: app/plugins/pinia.ts
  • Purpose: Set up Pinia state management with SSR hydration
  • Type: Universal (runs on both server and client)
  • Load Order: 1 (must load first)

Overview ​

The Pinia plugin initializes Pinia state management for the application. It handles SSR state hydration, ensuring that server-rendered state is properly restored on the client-side. This plugin must load first before any other plugins that use stores.

Key Features ​

  1. Pinia Initialization

    • Creates Pinia instance
    • Registers with Vue app
    • Provides Pinia instance globally
  2. SSR State Hydration

    • Serializes state on server
    • Stores in Nuxt payload
    • Restores state on client
  3. State Persistence

    • Server state serialized to payload
    • Client state restored from payload
    • Prevents hydration mismatches

Code Structure ​

typescript
import { createPinia, type StateTree } from 'pinia'

export default defineNuxtPlugin((nuxtApp) => {
  const pinia = createPinia()
  nuxtApp.vueApp.use(pinia)
  
  // Handle SSR state hydration
  if (import.meta.server) {
    // On server: serialize pinia state into payload
    nuxtApp.payload.pinia = pinia.state.value
  } else if (nuxtApp.payload && nuxtApp.payload.pinia) {
    // On client: restore state from payload
    pinia.state.value = nuxtApp.payload.pinia as Record<string, StateTree>
  }
  
  // Provide pinia instance for use in other plugins
  return {
    provide: {
      pinia
    }
  }
})

SSR Hydration Flow ​

Server-Side ​

  1. Pinia instance created
  2. Stores initialized with data
  3. State serialized to nuxtApp.payload.pinia
  4. State sent to client in HTML payload

Client-Side ​

  1. Pinia instance created
  2. State restored from nuxtApp.payload.pinia
  3. Stores hydrated with server state
  4. Prevents hydration mismatches

Usage ​

Pinia is automatically available throughout the application. No manual setup required.

Using Stores ​

typescript
// In components or composables
const authStore = useAuthStore()
const appDataStore = useAppDataStore()

Accessing Pinia Instance ​

typescript
const { $pinia } = useNuxtApp()

Store Structure ​

Stores are located in app/stores/ and automatically registered:

  • auth.ts - Authentication store
  • appData.ts - Application data store
  • search.ts - Search state store
  • download.ts - Download state store

State Serialization ​

Server-Side ​

typescript
nuxtApp.payload.pinia = pinia.state.value

State is automatically serialized to JSON and included in the HTML payload.

Client-Side ​

typescript
pinia.state.value = nuxtApp.payload.pinia

State is restored from the payload, ensuring consistency between server and client.

Dependencies ​

  • Pinia - State management library
  • Vue - Vue.js framework

Notes for Development ​

  • Must load first - Other plugins depend on Pinia
  • SSR hydration prevents state mismatches
  • State automatically serialized/restored
  • Pinia instance available globally
  • Stores can be used in plugins after Pinia loads