Skip to content
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

Open
5 tasks done
jeanmatthieud opened this issue Nov 29, 2024 · 4 comments
Open
5 tasks done

Unable to use Nuxt with SSR and cookies #361

jeanmatthieud opened this issue Nov 29, 2024 · 4 comments
Labels
🔍️ pending triage This issue needs to be looked into

Comments

@jeanmatthieud
Copy link

Are you using Nuxt?

  • Check this box if you encountered the issue using Nuxt and the included module.

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:

[1:04:47 PM]  ERROR  [pinia-plugin-persistedstate] [nuxt] A composable that requires access to the Nuxt instance was called outside of a plugin, Nuxt hook, Nuxt middleware, or Vue setup function. This is probably not a Nuxt bug. Find out more at https://nuxt.com/docs/guide/concepts/auto-imports#vue-and-nuxt-composables.

  at Module.useNuxtApp (node_modules/nuxt/dist/app/nuxt.js:251:13)
  at Module.useRequestEvent (node_modules/nuxt/dist/app/composables/ssr.js:11:58)
  at readRawCookies (node_modules/nuxt/dist/app/composables/cookie.js:144:101)
  at Module.useCookie (node_modules/nuxt/dist/app/composables/cookie.js:29:19)
  at Object.setItem (node_modules/pinia-plugin-persistedstate/dist/nuxt/runtime/storages.js:13:52)
  at persistState (node_modules/pinia-plugin-persistedstate/dist/nuxt/runtime/core.js:42:13)
  at store.$subscribe.detached (node_modules/pinia-plugin-persistedstate/dist/nuxt/runtime/core.js:73:29)
  at node_modules/pinia/dist/pinia.mjs:1450:21
  at callWithErrorHandling (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:200:19)
  at callWithAsyncErrorHandling (node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:207:17)

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

System:
    OS: Linux 5.15 Debian GNU/Linux 12 (bookworm) 12 (bookworm)
    CPU: (8) x64 11th Gen Intel(R) Core(TM) i7-11370H @ 3.30GHz
    Memory: 9.23 GB / 15.52 GB
    Container: Yes
    Shell: 5.2.15 - /bin/bash
  Binaries:
    Node: 20.9.0 - /usr/local/bin/node
    Yarn: 1.22.19 - /usr/local/bin/yarn
    npm: 10.9.1 - /workspaces/[project]/node_modules/.bin/npm
    pnpm: 8.10.2 - /usr/local/share/npm-global/bin/pnpm

Used Package Manager

npm

Validations

@jeanmatthieud jeanmatthieud added the 🔍️ pending triage This issue needs to be looked into label Nov 29, 2024
@prazdevs
Copy link
Owner

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 useAuthStore in deeper scopes instead of at the root, this will defer the moment the store is retrieved, and may make it so the plugin is properly initialised.

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 pinia-plugin-persistedstate) so you can also try adding dependsOn: ['pinia-plugin-persistedstate'] on your Nuxt plugin config, but I'm not sure this will really solve the issue.

@jeanmatthieud
Copy link
Author

jeanmatthieud commented Dec 20, 2024

Hi,
Thanks for your response.
I already tried to use the store directly in the functions, but I still get the same error.
I'm not sure how I can use the 'dependsOn', as this code is not in a plugin.

When does Pinia try to restore the cookies (what triggers it)?
I don't understand why the stores are called outside "a plugin, Nuxt hook, Nuxt middleware, or Vue setup function" as my code is an HTTP client, only used on Nuxt pages, plugins and so on. That's why I'm wondering when the cookies are "unpacked" into the store, to find what could possibly do it outside authorized scopes.

@prazdevs
Copy link
Owner

I will need a more complete reproduction to investigate, cause i cannot reproduce the error with what you sent in the original message.
Pinia restores cookies when the pinia plugin is initialised which only happens in Vue context.

@stephenjason89
Copy link

stephenjason89 commented Dec 21, 2024

@jeanmatthieud I have fixed this a long time ago. Pr was not merged. Have a look at #99
And #97 (comment)

Maybe this time @prazdevs may reconsider the PR since not only I have this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🔍️ pending triage This issue needs to be looked into
Projects
None yet
Development

No branches or pull requests

3 participants