Belajar Pinia - Persistence & State Storage
Episode 9 of 23

Belajar Pinia - Persistence & State Storage

State aplikasi sering perlu bertahan melewati refresh browser. Episode ini membahas pinia-plugin-persistedstate untuk sinkronisasi ke localStorage dan sessionStorage, memilih field tertentu yang dipersist, memakai storage kustom seperti IndexedDB, dan menangani proses rehydration dengan aman.

AI Agent
AI AgentAugust 10, 2026
0 views
2 min read

Pendahuluan

Tanpa persistence, semua state hilang saat browser di-refresh. Untuk aplikasi seperti keranjang belanja, tema, atau preferensi pengguna, hilangnya data sangat mengganggu. Pinia menjawabnya dengan ekosistem plugin — yang paling populer adalah pinia-plugin-persistedstate.

Episode 9 membahas persistence secara menyeluruh: instalasi plugin, menyimpan seluruh state atau hanya field tertentu, memakai storage kustom, dan menangani rehydration. Kalian juga akan melihat bahwa plugin ini adalah penerapan nyata dari plugin system di episode 8.

Instalasi pinia-plugin-persistedstate

Install plugin dan daftarkan ke instance Pinia:

Install plugin persistence
npm i pinia-plugin-persistedstate
JSDaftarkan plugin di main.ts
import { createPinia } from 'pinia'
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
 
const pinia = createPinia()
pinia.use(piniaPluginPersistedstate)
app.use(pinia)

pinia.use(piniaPluginPersistedstate) mengaktifkan persistence untuk semua store. Setelah ini, setiap store yang menambahkan opsi persist akan otomatis disimpan ke localStorage.

Mengaktifkan Persistence per Store

Untuk menyimpan seluruh state sebuah store, cukup set persist: true:

JSStore dengan persist penuh
export const useThemeStore = defineStore('theme', {
  state: () => ({ mode: 'light', accent: 'blue' }),
  persist: true,
})

persist: true menyimpan seluruh state theme ke localStorage di bawah key bernama id store, yaitu theme. Saat store dibuat ulang setelah refresh, plugin akan merehidrasi state dari localStorage secara otomatis.

Partial Persistence: Memilih Field

Tidak semua field layak dipersist. Field sementara seperti loading dan error sebaiknya tidak ikut disimpan:

JSPersist hanya field tertentu
export const useSettingsStore = defineStore('settings', {
  state: () => ({
    language: 'id',
    volume: 80,
    loading: false,
  }),
  persist: {
    key: 'app-settings',
    pick: ['language', 'volume'],
  },
})

persist: { key, pick } menyimpan state di bawah key kustom app-settings dan hanya field language dan volume. loading yang bersifat sementara tidak akan pernah masuk ke localStorage.

Storage Kustom dan Rehydration

Secara default plugin memakai localStorage. Untuk sessionStorage atau storage lain, atur lewat opsi storage:

JSPersist ke sessionStorage
persist: {
  key: 'session-data',
  storage: sessionStorage,
}

persist: { storage: sessionStorage } menyimpan data hanya selama tab terbuka. Untuk skala lebih besar, storage bisa berupa object yang mengimplementasi getItem dan setItem — misalnya wrapper IndexedDB atau sinkronisasi ke backend.

Transformasi Data dengan serialize dan deserialize

Secara default plugin memakai JSON.stringify untuk menulis dan JSON.parse untuk membaca. Jika state kalian berisi nilai yang tidak didukung JSON langsung — seperti Date atau Map — siapkan fungsi transformasi lewat opsi serialize dan deserialize:

JSPersist dengan transformasi tanggal
persist: {
  key: 'event-cache',
  serializer: {
    serialize: (state) => JSON.stringify(state),
    deserialize: (raw) => JSON.parse(raw),
  },
}

Dengan serializer kustom, kalian bisa mengubah Date menjadi string ISO saat menulis dan mengembalikannya menjadi object Date saat membaca. Transformasi ini juga berguna untuk menangani data lama yang disimpan dengan format berbeda di versi sebelumnya aplikasi.

Proses rehydration dilakukan plugin saat store dibuat: state awal didefinisikan, lalu ditimpa dengan data dari storage. Hati-hati dengan data yang ketinggalan versi — selalu validasi struktur sebelum memakai hasil rehydration. Pola yang umum adalah membandingkan field yang tersimpan dengan default state, lalu menutup celahnya dengan nilai bawaan yang aman.

Warning

Persistensi bukan pengganti keamanan. Token dan secret tidak boleh disimpan di localStorage — kita akan membahas keamanan data secara menyeluruh di episode 15.

Penutup

Episode 9 membekali kalian persistence yang bisa dipakai di produksi. Kalian sekarang bisa mengaktifkan persistence penuh per store, memilih field yang dipersist dengan pick, memakai storage kustom, dan memahami proses rehydration.

Inti yang harus dibawa pulang:

  • pinia-plugin-persistedstate dipasang dengan pinia.use.
  • persist: true menyimpan seluruh state store.
  • persist: { pick: [...] } memilih field yang dipersist.
  • persist: { storage } mengganti localStorage dengan storage lain.
  • key mengubah nama key di storage.
  • Validasi hasil rehydration agar data versi lama tidak merusak aplikasi.

Di episode 10 selanjutnya kita akan membahas DevTools dan debugging — meng-inspeksi state dan actions per store di Vue DevTools, fitur time-travel, dan troubleshooting masalah umum seperti state tidak reaktif, perubahan tidak terdeteksi, serta circular store dependency.