-
From VUejs docs: https://vuejs.org/guide/scaling-up/ssr.html#cross-request-state-pollution Nuxt docs recommend their own However, Are there any issues with using |
Beta Was this translation helpful? Give feedback.
Replies: 4 comments
-
Exact same question here |
Beta Was this translation helpful? Give feedback.
-
I would also like a clarification on this, composables that are disabled don't include them two at all so technically it's implicitly okay but no explicit information about it in docs. |
Beta Was this translation helpful? Give feedback.
-
They are indeed susceptible to cross request state pollution and are not SSR safe, they are quite simple composable and just keep a global state and share it across all vue instances (it's in the definition) so if in SSR you have multiple vue instances at the same time, since they keep the same reference to a single state, this single state is shared across requests. It might not show up in testing if multiple render never happen in parallel because the state is disposed of when there is no more vue instance. So be careful and only use those on the client. To make those methods SSR safe, the global state would have to be stored within a single app context (meaning you would need to pass it an app instance) and not globally
I do wonder where you saw this? Maybe in general but definitely not all composables are SSR friendly (some will cause hydration mismatch) or safe The methods nuxt share are not susceptible to this because they use an app context like that under the hood and that's why they ask you to always run those composables within a setup function so they can access the app context Vueuse does not have such magic available to it but they could be made optionally SSR safe if someone is willing to put in a PR to pass a component instance as a second argument and use the root of the instance to store the state |
Beta Was this translation helpful? Give feedback.
-
I use this instead: /**
* createSafeGlobalState
* ---------------------
* • Client – identical to createGlobalState (one singleton per tab).
* • Server – one singleton per *request* (stored on nuxtApp),
* so no cross-request state pollution.
*/
export function createSafeGlobalState<T>(factory: () => T) {
// One key per invocation of this helper
const key = Symbol('safeGlobalState');
// Client singleton – created once and kept forever
const getClientState = createGlobalState(factory);
return () => {
if (import.meta.client) return getClientState();
// 🌐 server – scoped to the current Nuxt app (= current request)
const nuxtApp = useNuxtApp() as any;
// Lazily initialise per request
if (!nuxtApp._safeGlobalStates) nuxtApp._safeGlobalStates = new Map<symbol, unknown>();
if (!nuxtApp._safeGlobalStates.has(key)) nuxtApp._safeGlobalStates.set(key, factory());
return nuxtApp._safeGlobalStates.get(key) as T;
};
} |
Beta Was this translation helpful? Give feedback.
They are indeed susceptible to cross request state pollution and are not SSR safe, they are quite simple composable and just keep a global state and share it across all vue instances (it's in the definition) so if in SSR you have multiple vue instances at the same time, since they keep the same reference to a single state, this single state is shared across requests. It might not show up in testing if multiple render never happen in parallel because the state is disposed of when there is no more vue instance. So be careful and only use those on the client.
To make those methods SSR safe, the global state would have to be stored within a single app context (meaning you would need to pass i…