search/app/plugins/favorites.client.ts

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()
}
})