37 lines
1.5 KiB
TypeScript
37 lines
1.5 KiB
TypeScript
import { useFavoritesStore } from '~/stores/favorites'
|
|
|
|
/**
|
|
* Hidratación cliente del store de favoritos.
|
|
*
|
|
* Por qué un plugin (y no sólo el `hydrate()` interno del store):
|
|
*
|
|
* Con Nuxt + @pinia/nuxt, el flujo en cliente es:
|
|
* 1. Se llama por primera vez a `useFavoritesStore()` desde un componente
|
|
* o layout → corre el factory del setup store. Si ahí leyéramos
|
|
* `localStorage`, los `items` quedarían poblados…
|
|
* 2. …pero inmediatamente después Pinia aplica el payload SSR (en el que
|
|
* `items` viaja vacío, porque el servidor no tiene `localStorage`),
|
|
* sobrescribiendo lo que acabábamos de hidratar.
|
|
*
|
|
* Resultado: la lista "se perdía" al recargar la página, aunque estaba
|
|
* perfectamente guardada en `localStorage`.
|
|
*
|
|
* Solución: este plugin corre con `enforce: 'post'`, o sea **después** de
|
|
* que el módulo de Pinia haya inyectado y rehidratado todos los stores con
|
|
* el estado SSR. En ese momento llamamos a `hydrate()`, que pisa el
|
|
* `items: []` recién aplicado con la lista real del navegador.
|
|
*
|
|
* Es `.client.ts` para que no corra en el servidor (no hay `localStorage`)
|
|
* y para evitar mismatches de hidratación de Vue: durante la primera
|
|
* pintura el HTML coincide con el servidor (lista vacía) y luego, ya en
|
|
* cliente, el contenido se rellena reactivamente al hidratar.
|
|
*/
|
|
export default defineNuxtPlugin({
|
|
name: 'favorites-hydration',
|
|
enforce: 'post',
|
|
setup() {
|
|
const favorites = useFavoritesStore()
|
|
favorites.hydrate()
|
|
}
|
|
})
|