3

Use case: Vue3 app using express as API backend. Express uses express-sessions to establish a server-side session which is sent to the browser and received in every subsequent request.

I'm trying to create a route guard to prevent access to certain routes if the session cookie doesn't exist.

"vue": "^3.0.11",
"vue3-cookies": "1.0.1",

I've installed the following NPM package

https://www.npmjs.com/package/vue3-cookies

Then in main.js

import VueCookies from 'vue3-cookies'
app.use(VueCookies);

Then in router/index.js

function requireAuth(to,from,next){
  console.log(this);
  console.log(this.$cookies.get('_ga'))
  next();
}

const routes = [
  {
    path: '/',
    name: 'ProtectedRoute',
    component: ProtectedRoute,
    beforeEnter:requireAuth
  }

const router = createRouter({
  history: createWebHistory(process.env.BASE_URL),
  routes
})

Error: [Vue Router warn]: Unexpected error when starting the router: TypeError: Cannot read property '$cookies' of undefined

I've tried

this.$cookies.get('_ga')
Vue.$cookies.get('_ga')
window.$cookies.get('_ga')

None work.

I've also tried importing Vue into the index.js file but it fails, probably because in Vue3 you cannot import Vue into a component Vue.js 3: Cannot import Vue global object

The problem seems to be that this,Vue and window are all undefined. I've also tried the solution here `this` undefined in vue-router beforeEach

router.beforeEach((to,from,next) => {
  console.log(router.app); //still undefined!
});

Help!

3
  • What exactly are you trying to achieve? Why are you trying to get cookies in beforeEach? Commented Jun 1, 2021 at 14:07
  • Also maybe the problem is with the package, have you tried to use document.cookie? and see if it outputs something? Commented Jun 1, 2021 at 14:10
  • Your context is wrong, I think you could try with Vue.$cookies (import Vue first) Commented Jun 1, 2021 at 14:13

4 Answers 4

8

This worked for me:

//router.js
import { useCookies } from "vue3-cookies";
const { cookies } = useCookies();

console.log(cookies.get('...'));
Sign up to request clarification or add additional context in comments.

1 Comment

I tried this in my vue 3 app, its not working. I use options API like below data(){ return { cookies : useCookies(), } } then access it in mounted method like this.cookies.set('token','testing') But its not working
3

Vue Router 4 removes router.app, but you could add it yourself when setting up the router:

// main.js
import router from './router'

const app = createApp(App)

app.use(router)
router.app = app

app.mount('#app')

Then in the router config script, you could use that reference to get at app.config.globalProperties.$cookies (the global added by vue3-cookies):

// router.js
const router = createRouter({
  history: createWebHistory(),
  routes
})

function requireAuth(to, from, next) {
  const { $cookies } = router.app.config.globalProperties
  console.log('_ga', $cookies.get('_ga'))
  next()
}

export default router

demo

2 Comments

Thank you! Is this the right/vue way of doing this? it seems a little hacky.
The "right" way is debatable, but I agree it's not ideal. The Vue Router docs recommend this way of attaching app to router, so I'd say it's a "vue" way to do it.
3

Following what tony19 provided, I found another way that worked for me. They removed router.app and it seems trying to add it myself doesn't work. So instead, I just... exported the app instance from my main.js:

// main.js
export { app };

and imported in the router:

// router.js
import { app } from '...'

Now I could access the app instance's config, including $cookies.get method:

console.log(app.$cookies.get('...'))

Comments

2

I don't know if it will help anybody, but Syll's answer (sorry, can't comment the answer, don't have enough rep) lead me to noticing something I did wrong and wasn't working for me: In my case I wasn't using {} when setting the const, so I had to call .cookies() method on the object returned by useCookies() from vue3-cookies library. Like this:

import { useCookies } from "vue3-cookies";
const cookies_manager = useCookies();

console.log(cookies_manager.cookies.get('myCookieName'));

This should be avoidable by using const { cookies } = useCookies(); (note the curly braces) instead.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.