Plugin adalah cara Pinia memperluas semua store sekaligus. Episode ini membahas cara membuat plugin dengan pinia.use, menambah properti global ke store, menerima opsi plugin lewat argumen options, serta memakai $subscribe dan $onAction untuk observability di level store.

Pinia dirancang agar bisa diperluas. Alih-alih mengulang kode yang sama di setiap store — menulis logger, menambahkan akses router, atau sinkronisasi localStorage — kalian bisa menulis plugin sekali dan menerapkannya ke semua store secara otomatis.
Episode 8 membahas mekanisme plugin Pinia: struktur plugin dengan pinia.use, menambah properti global ke store, menerima opsi plugin, serta dua API observability level store: $subscribe dan $onAction.
Plugin adalah function yang dipasang lewat pinia.use(). Ia menerima satu context berisi pinia, app, store, dan options:
export function loggerPlugin({ store }) {
store.$subscribe((mutation, state) => {
console.log(`Store ${store.$id} berubah`, mutation.type, state)
})
}Plugin dipasang setelah instance Pinia dibuat:
import { createPinia } from 'pinia'
import { loggerPlugin } from '@/plugins/logger'
const pinia = createPinia()
pinia.use(loggerPlugin)
app.use(pinia)pinia.use(loggerPlugin) mendaftarkan plugin ke instance Pinia. Context { store } memberi plugin akses ke setiap store yang baru dibuat, sehingga store.$id bisa dibaca untuk identifikasi.
Plugin bisa menempelkan properti baru ke setiap store:
import { ref } from 'vue'
export function localSyncPlugin({ store }) {
const saved = localStorage.getItem(store.$id)
if (saved) {
store.$patch(JSON.parse(saved))
}
store.$subscribe((_mutation, state) => {
localStorage.setItem(store.$id, JSON.stringify(state))
})
}store.$patch(JSON.parse(saved)) merehidrasi state dari localStorage saat store dibuat, dan $subscribe menyimpan perubahan berikutnya. Plugin ini adalah fondasi dari persistence yang akan disempurnakan di episode 9.
Kadang plugin butuh konfigurasi per store. Opsi diberikan lewat options — argumen ketiga defineStore:
export function persistPlugin({ options }) {
if (options.persist === true) {
console.log(`Store akan dipersist`)
}
}
// Di definisi store
export const useThemeStore = defineStore('theme', {
state: () => ({ mode: 'light' }),
persist: true, // dibaca plugin lewat options
})options.persist === true dibaca plugin dari opsi store. Inilah pola yang dipakai library pinia-plugin-persistedstate — dan itulah cara menambah konfigurasi ke store tanpa mengubah inti Pinia.
Selain plugin, kedua API ini bisa dipakai langsung di komponen:
store.$subscribe mendengarkan setiap perubahan state — berguna untuk autosave dan analytics.store.$onAction mendengarkan pemanggilan action — berguna untuk logging dan tracking.store.$subscribe((mutation, state) => {
console.log(mutation.storeId, mutation.type, state)
})
store.$onAction(({ name, args, after, onError }) => {
console.log('Mulai action', name, args)
after((result) => console.log('Selesai', result))
onError((error) => console.error('Gagal', error))
})store.$onAction(({ name, args, after, onError }) => ...) menangkap nama action, argumen, hasil setelah selesai, dan error. Kombinasi $subscribe dan $onAction ini adalah dasar observability Pinia.
Tip
Secara default, $subscribe hanya aktif selama komponen yang mendaftarkannya masih ada. Kirim opsi { detached: true } agar berlangsung lebih lama — akan dibahas di episode 13.
Episode 8 membuka sistem plugin Pinia. Kalian sekarang bisa menulis plugin dengan pinia.use, menambah properti global ke semua store, membaca opsi store dari options, dan memakai $subscribe serta $onAction untuk observability.
Inti yang harus dibawa pulang:
pinia.use.pinia, app, store, dan options.defineStore.$subscribe mendengarkan perubahan state.$onAction mendengarkan pemanggilan action, termasuk hasil dan error.Di episode 9 selanjutnya kita akan membahas persistence dan state storage — menyimpan state ke localStorage dan sessionStorage dengan pinia-plugin-persistedstate, memilih field tertentu yang dipersist, memakai storage kustom, dan menangani rehydration. Plugin dari episode 8 akan kita pakai secara nyata.