Krutie / nuxt-3-lessons

nuxt 3 lessons and issues
3 stars 1 forks source link

pinia-plugin-persistedstate using sessionStorage #1

Closed artknight closed 6 months ago

artknight commented 7 months ago

Hi Krutie, Sorry to be reaching out to you this way, but I could not find any other way to contact you. I love your blog! I am working on an app using nuxt3 + pinia. I started using the https://github.com/prazdevs/pinia-plugin-persistedstate plugin with sessionStorage. However, I had to set ssr: false in my nuxt.config.js because the app would not run, throwing the sessionStorage is undefined error. I am wondering if you happen to have an idea what I could do to solve the issue and have the server-side rendering enabled.

Thanks, Art

Krutie commented 7 months ago

No problem @artknight Happy to have a look if you can please provide a Stackblitz or Codesandbox with the repro of your issue? Thanks.

artknight commented 6 months ago

@Krutie I have created a project on stackblitz to show the error. https://stackblitz.com/edit/nuxt-starter-up65bq?file=pages%2Findex.vue

please let me know your thoughts

Krutie commented 6 months ago

Thanks for providing the repro, @artknight

Check out the working Stackblitz once you read the details below. Hope it helps.

Store setup

Replace sessionStorage with persistedState.localStorage - and leave the ssr:false commented out in nuxt.config. (Reference)

import { defineStore } from 'pinia';

export const useUserStore = defineStore('user', {
  // ...
  persist: {
    // storage: sessionStorage, // this **needs** `ssr:false`
    storage: persistedState.localStorage,
    // storage: persistedState.sessionStorage, // this works as well
  },
});

Now to see the persistedState plugin in action, do one of the followings:

Invoke persistedState automatically

In auth.js middleware, use $persist method available on store to invoke persistedState automatically, without user interaction, on page load.

export default defineNuxtRouteMiddleware((to, from) => {
  const userStore = useUserStore();
  userStore.$persist();
});

This way you should be able to see the user object in localstorage on page load.

However, $persist forces persistance and not recommneded for usage unless you really need it. (Reference)

Invoke persistedState on user interaction

So, here's how you do it without using $persist method. On the /login page, create a login action.

<script setup></script>

<template>
  <h1>login</h1>
  <button @click="userStore.$state.auth = true">Login</button>
  <pre>{{ userStore.$state }}</pre>
</template>

<script setup>
import { useUserStore } from '@/stores/user';
const userStore = useUserStore();
</script>

Now, when we click the Login button, then the user object should be visible in the localStorage section in the devTool.

artknight commented 6 months ago

@Krutie Thank you! It seems using persistedState did the trick. However, on page refresh the session storage is supposed to persist but it does not, so the user gets redirected to the login page every time!

PS: Whats the best way to contact you in the future (twitter DM, email, etc...)?

Krutie commented 6 months ago

Glad to hear @artknight !

If you have any of my repo-related question, you can raise an issue on Github or Twitter DM is also fine. For Nuxt related issues, you can also try Nuxt Discord server - that might be lot quicker than me sometimes.

artknight commented 6 months ago

Hey, I see you closed the issue but it was not completely resolved... imho. On page refresh the session storage is supposed to persist but it does not, so the user gets redirected to the login page every time!

Also, not sure how to DM you on twitter as you do not have the button enabled.