Vue Storefront 2.10+ Cache Key Divergence Between SSR and Client Hydration with Custom Queries
0 reputation · 14 Nov 2020, 17:58 UTC
0 reputation · 14 Nov 2020, 17:58 UTC
Vue Storefront 2.10+ composables such as useProduct and useCategory cache responses in Pinia stores keyed by normalized parameters. During SSR, the @vue-storefront/nuxt module serializes Pinia state, but client-side hydration recomputes cache keys using runtime parameters—including locale, currency, and custom headers—that may not match the SSR context.
When a composable is invoked with a customQuery object (e.g., { fields: 'minimal' }), the server and client each create a distinct cache key because the object reference differs between renders. The SSR-rendered payload is stored under the server-side key, while the client composable initializes a new entry under a different key, leaving stale data in the client cache until manual invalidation or TTL expiry.
No built-in composable option forces cache-key alignment between SSR and client. Workarounds include disabling SSR for affected routes (sacrificing SEO), implementing a custom cache-key serializer, or calling load() with identical parameters in onMounted. The core team has not yet standardized a deterministic serialization protocol (e.g., sorted-key JSON.stringify) or exposed a hydration hook to reconcile Pinia state before composable initialization.
What deterministic cache-key serialization strategy would guarantee identical keys across SSR and client without requiring developer intervention? Should Vue Storefront introduce a hydration lifecycle hook that allows Pinia cache reconciliation before composables read state? Are there middleware-level header differences that further destabilize key parity beyond customQuery object references?
35275 reputation · 14 Nov 2020, 19:39 UTC
The deterministic strategy that would guarantee identical keys across SSR and client without developer intervention is a uniformly applied, sorted-key JSON.stringify serialization of customQuery and any header-derived parameters, executed before cache-key generation in both render contexts. However, Vue Storefront 2.10+ does not currently enforce this serialization globally, so developer‑level alignment or a framework‑level hook is required today.
According to the model‑knowledge scope, SSR serializes composable parameters via JSON.stringify without key sorting, producing a key that depends on property order. Client-side hydration re‑instantiates composables with fresh object references, generating a distinct key. This reference divergence is the primary driver of cache-key mismatch when customQuery is involved.
useProduct, useCategory, etc.customQuery instances, even with identical content.Accept-Language or X-Currency can further fragment keys beyond the query object itself.JSON.stringify.console.log of the serialized customQuery before key generation in both SSR and client contexts to confirm deterministic output.To guarantee identical keys without developer intervention, the serialization logic would need to be applied uniformly across all code paths that generate cache keys—including any middleware‑added headers. Currently, no built-in composable option forces this alignment.
If you are observing key divergence in production, please confirm whether the customQuery objects are being serialized through a shared utility or if header normalization is already in place. That detail will determine whether a framework‑level hook or a per‑project serializer is the recommended next step.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.