-
-
Notifications
You must be signed in to change notification settings - Fork 129
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Unable to use Nuxt with SSR and cookies #361
Comments
I see a couple of potential issues/solutions. Calling the store at the very root of your plugin makes it so the plugin might not be initialised yet (see #352), the store itself works because of how pinia can work outside of a Vue instance, but it will defer plugin initialisations. You can try calling For example : async function signInWithToken(newToken: string) {
// call composable here, I dont think there needs to be a `runWithContext` or such
const authStore = useAuthStore()
try {
authStore.token = newToken;
await refreshUser();
} catch (e) {
authStore.token = undefined;
authStore.refreshToken = undefined;
}
} This should make it work. Next version will also expose an explicit name for this plugin (originally called |
Hi, When does Pinia try to restore the cookies (what triggers it)? |
I will need a more complete reproduction to investigate, cause i cannot reproduce the error with what you sent in the original message. |
@jeanmatthieud I have fixed this a long time ago. Pr was not merged. Have a look at #99 Maybe this time @prazdevs may reconsider the PR since not only I have this issue. |
I also having this issue, the only way it triggers the error is when the user is getting redirect back from Google auth... The issue doesn't trigger in any other navigation or situation for me... So to suppress the issue for now, I cloned the repo and defined a static config for now, but I hope we find a better solution: import type { Pinia, PiniaPluginContext } from 'pinia'
import { defineNuxtPlugin } from '#app'
import { destr } from 'destr'
import { createPersistence } from './core'
import { storages } from './storages'
function piniaPlugin(context: PiniaPluginContext) {
const options = {
storage: 'localStorage',
auto: false,
key: `%id`,
debug: false,
cookieOptions: {
sameSite: 'lax',
},
}
createPersistence(
context,
p => ({
key: options.key
? options.key.replace(/%id/g, p.key ?? context.store.$id)
: (p.key ?? context.store.$id),
debug: p.debug ?? options.debug ?? false,
serializer: p.serializer ?? {
serialize: data => JSON.stringify(data),
deserialize: data => destr(data),
},
storage: p.storage ?? (options.storage
? options.storage === 'cookies'
? storages.cookies(options.cookieOptions)
: storages[options.storage]()
: storages.cookies()),
beforeHydrate: p.beforeHydrate,
afterHydrate: p.afterHydrate,
pick: p.pick,
omit: p.omit,
}),
options.auto ?? false,
)
}
export default defineNuxtPlugin({
name: 'pinia-plugin-persistedstate',
setup({ $pinia }) {
($pinia as Pinia).use(piniaPlugin)
},
}) |
When you're coming from Google Auth, the site uses SSR (inconsistencies between server cookies and browser cookies). When you're only navigating on your site (without full refresh), the cookies are only set on the client side (browser). |
I'm also running into this issue in my Nuxt 3 app when trying to use a Pinia store from route middleware.
export default defineNuxtRouteMiddleware((to, from) => {
const loggedIn = false
if (!loggedIn) {
const nuxtApp = useNuxtApp()
const alertStore = useAlertStore(nuxtApp.$pinia)
alertStore.createAlert('error', 'Please log in to continue.')
return navigateTo('/')
}
}) When this middleware runs server-side, I get the exact error posted in the original comment. There is no error when the middleware runs client-side. |
As a workaround, I figured out that when the code runs server-side I can manually set the cookie Pinia uses rather than working with the store itself. Then, the Pinia store will read the cookie when the client application loads: const alert = { 'error', 'Please log in to continue.' }
if (import.meta.client) {
alertStore.createAlert(alert)
return abortNavigation()
}
else {
const alertCookie = useCookie('alerts')
alertCookie.value = JSON.stringify({ alerts: [alert] })
return navigateTo('/')
} |
I also get this error. If I try to update the state in the ssr context, I get the error: "A composable that requires access to the Nuxt instance was called outside of a plugin, Nuxt hook, Nuxt middleware, or Vue setup function." I even tried to call store.$persist() manually in ssr context (I know that this should not be done, I was just trying to solve the problem), but this, unfortunately, did not help, I also get the error: "A composable that requires access to the Nuxt instance was called outside of a plugin, Nuxt hook, Nuxt middleware, or Vue setup function." |
Are you using Nuxt?
Describe the bug
I have a Nuxt project, with pinia + pinia-plugin-persistedstate
I want to be able to use the cookies with SSR.
Pinia is used to store the auth token of the user, and refresh it if required.
I'm using the strore in a custom Nuxt plugin.
It works fine on the client side.
However, I realized that I have an issue if the server side tries to update the cookie through the Pinia store (eg. the new token is retrieve during SSR, and should be stored to the cookie to be transmitted to the client side).
Is it even possible?
I have the following issue when I try to update the store during SSR:
It is quite hard to write a reproduction, and it took me a lot of time to find the issue.
Reproduction
https://stackblitz.com/edit/nuxt-pinia-perstitedstate
System Info
Used Package Manager
npm
Validations
The text was updated successfully, but these errors were encountered: