The rule: one instance per request
AKweri instance owns a cache. On the server, a module-level singleton is shared across every request, so one user’s data bleeds into another’s. The fix is to create instances per request and provide them down the component tree — never at module scope.
Nuxt
A Nuxt plugin runs once per request on the server (and once on the client), which is the right place to instantiate.Why each piece
createKweriClientsandcreateVuePathHooksboth live in the plugin, not at module scope — the hook sets bind to a specific instance, so they must be request-scoped too. They don’t touchonUnmounted/watchuntil a component calls a hook insetup, so this is safe.presets.ssruses a longerstaleTimeandmaxRetries: 0, and sets no devtools.destroyAll()onapp:renderedreleases the request’s instances. It’s optional — kweri’s automatic GC only runs in the browser (it’s gated ondocument), so no server-side timer is ever started.
Other frameworks
The principle is identical: callcreateKweriClients(...) per request inside your handler/loader and pass it through context (Vue app.provide, a request-scoped DI container, etc.). Anything that creates an instance must run inside the request.
Data transfer (hydration)
kweri does not yet ship built-in SSR cache transfer (serialize on the server → embed in the payload → restore on the client). Without it, the server fetches and renders, then the client refetches the same data on hydration — correct, just not optimal. To avoid the refetch today, bridge manually through your framework’s payload (e.g. NuxtuseState):
First-class
dehydrate() / hydrate() helpers are planned. Until then, the manual bridge above (or simply accepting the client refetch) is the recommended approach.