Nuxtjs store undefined in middleware on refresh - vue.js

I'm using nuxt js for my web app, I need to keep the store when I refresh the page, even in middleware or the page itself.
I'm using vuex-persistedstate;
import createPersistedState from "vuex-persistedstate";
export default ({ store }) => {
if (process.client) {
window.onNuxtReady(() => {
createPersistedState({})(store);
});
}
};
One of the solutions that I tried is to use cookies in the store, but my data is very huge and I need it in the local storage.
I think it's something related to SSR or server middleware, I tried a lot to figure out how to solve it, but nth is working.

It is impossible because we are not able to access localStorage when component is rendering on the server side. You should either turn off ssr to use localStorage or try to reduce the size of your data to put it in cookies.

Related

Initate Session on page load

I have a requirement where I need to set Global Axios header and refresh session(Calling multiple Api's). In vuejs we would have a App.vue which is the entry point for our application we would do these types of processing in that.
App.vue
export default {
async created(){
await this.$store.dispatch('initateSession');
}
}
The benefits of doing this is that this is called only once(not on every route change), and on every page load, I am looking to implement the same functionlity in Nuxt.
Now as we dont have any App.vue in case of Nuxt one solution that i could think off is to create a middleware for this , which can work but that will be called on every route change I dont want that, does anyone know any workaround for it?
Instead of middleware you can create a plugin:
plugins/session.js:
window.onNuxtReady(() => {
// Do something
})
And then add it to the plugins section inside nuxt.config.js.

How to get access beforeCreate() global app in Nuxt?

I want to get access beforeCreate() app cycle method in Nuxt and load data from localStorage to Vuex store, how can I do that?
You could use Nuxt middleware to achieve a beforeCreate() effect.
// /nuxtproject/middleware/store_check.js
export default function ({ store }) {
store.dispatch('stateModule/stateAction')
}
// /nuxtproject/pages/index.vue
export default {
components: {
Header
},
middleware: 'store_check',
}
As for loading from localStorage, you can use it with the middleware solution above provided Nuxt is running in SPA mode - because localStorage isn't natively available on Nuxt Universa/SSR mode.
Had this same problem after spending some hours and this other stackoverflow answer explains why (with alternatives)
https://stackoverflow.com/a/57512785/842834

Nuxt.js with vuex-persist - persisted state not available in asyncData upon page refresh

Upon first page refresh, the asyncData function is not able to fetch the persisted state. When I follow another NuxtLink, and go back to this page, while the state is not mutated in the meantime, the data is there. This means the persisted state is not available on the server side at first load/refresh. LocalStorage is where I choose to persist the relevant state items.
A pages component that uses asyncData:
asyncData({ app, params, store }) {
//its not available upon first refresh, but is after following a random nuxtlink and going back
const cartProducts = store.getters.getCartProducts
},
store/index.js is straightforward. Unfortunately, the state is completely empty in asyncData upon first page refresh.
getCartProducts(state) {
return state.cart.products
},
vuex-persist.js imported properly with mode 'client' as recommended in the Github Readme
import VuexPersistence from 'vuex-persist'
/** https://github.com/championswimmer/vuex-persist#tips-for-nuxt */
export default ({ store }) => {
window.onNuxtReady(() => {
new VuexPersistence({
key: 'cartStorage'
/* your options */
}).plugin(store)
})
}
How can I make sure the relevant store terms from local storage are persisted before asyncData is called?
You can't do this. Its impossible. There is no localstorage on server. And asyncData executed on server on first load/refresh. So there is no way to get data from in asyncData from localstorage on server even theoretically.

How to implement Auth0 server-side with Nuxtjs?

I have a Nuxt app with authentication already running in universal mode.
I'm trying to convert the authentication service to Auth0. I'm following the Vue quickstart, but I discovered that auth0-js is a client side library since it uses a lot of 'window'-stuff that is not available on the server-side of Nuxt.
However, I got it kind of working by making it a client-side plugin and wrap all functions (that is calling the authservice in the lifecycle hooks) in a process.client check. It works "kind of" because when going to the protected page whilst not logged in, it flashes the page before being redirected to login page (since its rendered on the server-side as well, but the check only happens once it's delivered on the client side I presume).
My question now is: What can I do in order to add the check to server-side as well? (or at least make sure that the protected pages isn't flashed before being redirected).
What I've tried so far:
Saving the payload and the logged-in state in the store and check in some custom middleware, but that didn't do the trick.
Also, it seems to me that #nuxt/auth is outdated or something and the nuxt auth0 example as well. It uses auth0-lock while I'm using the new auth0 universal.
Anyone have suggestions on how to solve this issue? Thanks in advance!
not sure if this will be any help and have only answered a few questions (other account long time ago).
Update.. I read my answer then the question title (I think my answer does cover some of your context), but in regards to the title you could also look at using auth as a plugin. You can then handle stuff there before the page is hit.
I am not sure how your code is implemented, but this may help (hopefully).
If you are not using Vuex, I strong recommend it. Nuxt Vuex Store Guide
// index/store.js
// At least have the store initialized, but its most likely going to be used..
// page.vue
<template>
...
<div v-else-if="!$auth.loggedIn">
{{ test }}
</div>
...
...
data() {
if (!this.$auth.loggedIn) {
const test = 'Only this will load, no flash'
return { test }
}
}
$auth.loggedIn is built in, I read it ..somewhere.. in the docs
This will solve the no flash issue, you can also take advantage of a loader screen and asyncData to check the state before rendering the view to avoid a flash and populate data if it hangs.
You could also try using Vuex Actions, I am currently playing with these 2 in the process of where I am now. Learning about nuxtServerInit()
// store/index.js
import axios from 'axios'
export const actions = {
nuxtServerInit ({commit}, {request}) {
// This is good if you have the user in your request or other server side stuff
if (request.user) commit('SET_USER', request.user)
},
async GET_USER({ commit }, username) {
const user = await axios.get(`/user/${username}`)
if (user) commit('SET_USER', user)
}
}
export const mutations = {
SET_USER(state, user) {
// simple set for now
state.auth.user = user || null
}
}
The second one is combined using the fetch() method on the page itself.
// page.vue
async fetch({ $auth, store }) {
await store.dispatch('GET_USER', $auth.$state.user)
}
Now you can call $auth.user in your code as needed.
$auth.user is another built in I read ..somewhere..
You can also call $auth.user with the $auth.loggedIn to check if user exists on top of being logged in $auth.user && $auth.loggedIn.
It may be this.$auth.<value> depending on where you are trying to reference it.
I learned the asyncData() gets call first and logs in my server, then data() logs values in the server console as well (false, null), but in my Brave console they're undefined, i'd like an answer to that lol
I have been struggling with trying to get Auth0 to work how I wanted with JWTs, but as I kept crawling I found useful bits along the way (even in old demos such as the one you mentioned, just nothing with the lock stuff...). Also in terms of express and my API in general... Anyways, hope this helped (someone).

Change Apollo endpoint in Apollo provider

Is there a way to change the Apollo endpoint after having created the Apollo client? I would like to have the user to input their own endpoint.
httpEndpoint can be a function, and it is called on each query.
As #wrod7 mentioned, you could use localStorage, but global variable should be enought
// vue-apollo.js
export { defaultOptions }
// main.js
import { createProvider, defaultOptions } from './vue-apollo'
window.apolloEndpoint = defaultOptions.httpEndpoint
new Vue({
router,
apolloProvider: createProvider({
cache,
httpEndpoint: () => window.apolloEndpoint,
}),
render: h => h(App),
}).$mount('#app')
and you can set apolloEndpoint anywhere you like, i am using window. to make eslint happy
httpEndpoint is called with current query, so you can conditionally return endpoint based on operationName
vue-apollo got support for multiple clients, it might be useful if you want to override endpoint only on some queries, but i thinks this offtopic
I am doing this on one of my applications. I store the URL string in localstorage or asyncstorage on mobile. you can check for the string when the app loads and have the user enter one if there isn't a url string stored. the application would have to refresh after entering the url and saving it to localstorage.