Navigating Cookies in Vue3: a guide to working with them beyond components

I am facing a challenge in my Vue 3 project where I need to securely store the access token for the logged-in user using cookies. To achieve this, I have integrated the 'vue-cookies' npm package into my application.

<

While the cookie implementation works seamlessly within components, I encountered an issue when attempting to access cookies outside of components.

Below is an excerpt from my main.ts file:

import { createApp } from 'vue'
import { createPinia } from 'pinia'
import VueCookies from 'vue-cookies'
import router from './router'
import App from './App.vue'

import './assets/main.css'

const app = createApp(App)

app.use(createPinia())
app.use(router)
app.use(VueCookies, { expires: '15m' })

app.mount('#app')

Inside the "LoginItem.vue" component, I successfully retrieved the access token using $cookies within the script tags:

// ...
    const $cookies = inject<VueCookies>('$cookies')
    const token = ref('')
// ...

    onMounted(() => {
      const accessToken = $cookies?.get('accessToken')
      if (accessToken) {
        token.value = accessToken
      }
    })

However, I wanted to create a global module or file to handle common operations with the access token and attempted to do so in a separate file named "auth.ts". Here's the code snippet:

import { inject } from 'vue'
import type { VueCookies } from 'vue-cookies'

const $cookies = inject<VueCookies>('$cookies')

export const getToken = (): string => {
  return $cookies?.get('accessToken')
}

Unfortunately, the $cookies variable always returns undefined in this context. How can I resolve this issue?

Furthermore, I'm unsure if managing access tokens in this manner aligns with the recommended approach in Vue 3. Should I explore alternative methods for handling access tokens within my application?

Answer №1

Using inject in places other than component setup and options API hooks that run concurrently (such as created, etc) is a mistake. The provide/inject mechanism relies on the component hierarchy to determine which value to inject, so it's crucial to use it accordingly.

While a value can be directly imported and utilized, provide/inject serves specific purposes like dependency injection and circumventing circular dependencies.

In the plugin instance mentioned here, it's only exposed within the application instance as app.$cookies. Although it can be used in non-component modules, caution should be taken to prevent circular dependencies. Failing to resolve CD efficiently may hinder bundling the application in certain environments. One way to mitigate this issue is by isolating the application instance into a separate module and refraining from instantaneously referencing the root component upon import, e.g., app.js:

import { createApp, h } from 'vue'
export const app = createApp({ render: () => h(App) })

Subsequently, import app in main.js and other modules requiring access to app.$cookies.

Opting for reactive global store over cookies as the singular source of truth is advisable, with the ability to sync the store with cookies or local storage. This synchronization can be easily achieved using Pinia store and persistence plugin, given Pinia's current usage here. Importing stores directly anywhere helps avoid complications associated with CD as discussed earlier.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

ASP.NET Sessions Timeout

I'm encountering issues with sessions in asp.net. Despite my efforts to troubleshoot by searching online, I haven't been able to pinpoint why the session expires after a few minutes. This project wasn't developed by me, and I'm not an e ...

A step-by-step guide on updating a deprecated typings package manually

Currently, I am developing a NodeJS application using TypeScript and incorporating numerous Node packages. However, not all of these packages come with TypeScript definitions, so Typings is utilized to obtain separate definition files. During the deployme ...

"Dealing with Vue.js: Issue with passing a property to the

Check out the code snippet below: export default new Router({ routes: [ { path: '/noticia/:id', name: 'Noticia', component: Noticia, props: true } ] }) export default { name: 'Noticia&apo ...

display of information with v-element

How do I properly load the v-component and v-component2? 1) Within the Vue component 1: watch: { loader () { axios.post("/laravel_route", { param: value }) .then (response => { $("#section").html(re ...

What is the best way to leverage Typescript's declaration merging along with an interface imported from an external module?

https://www.typescriptlang.org/docs/handbook/declaration-merging.html The hyperlink provided above offers insights into declaration merging using interfaces. It's something I'm interested in exploring further, particularly with interfaces that h ...

You cannot assign the type 'void' to the type 'ObservableInput<Action>'

I'm encountering a type error when I attempt to dispatch an observable of actions within my effect. The error message I'm receiving is as follows: @Effect() rideSummary$: Observable<Action> = this.actions$.pipe( ofType<GetRi ...

Transforming a jQuery menu into an active selection with Vue JS

I am looking to transition away from using jQuery and instead utilize Vue for the front end of a menu. Specifically, I need to add an active class and a 'menu-open' state to the appropriate nested list items, similar to what is achieved in the pr ...

What is the best way to position a div in the top right corner of my form using Bootstrap?

I have a form displaying some detailed text about elements in my application. Located outside this form is an "add new item" button that redirects the user to a new page for adding a new item. The current placement of this button is on the upper left corn ...

Managing multiple layouts in Nuxt.js when dealing with child pages - a comprehensive guide

Exploring the world of Nuxt.js and Vue.js for the first time has been an exciting journey. I am currently working on creating a template where I need to have two columns, with each column displaying different data. layouts/content.vue: <template> ...

Creating a dynamic type class in TypeScript that can inherit characteristics from another class

Can a wrapper class be designed to dynamically inherit the properties of another class or interface? For instance... interface Person { readonly firstName: string; readonly lastName: string; readonly birthday?: Date } class Wrapper<T> { ...

Getting into a dynamic named property inside another object in angular can be achieved by utilizing bracket notation

I encountered an issue in my Angular 8 project where I create an object from a JSON, but there is a dynamic property whose name is unknown until runtime. This causes problems when trying to access the value of that dynamic property within another object, l ...

Adding a library (typings) to a standalone instance of Monaco Editor: Step-by-step guide

My editor setup includes the following: editor.create(this._element, { language: "javascript", minimap: { enabled: false }, automaticLayout: true, readOnly: this.props.readOnly, }); In orde ...

"Launching a Vue.js SSR server in a Docker container: A step-by-step guide

I am working on a vuejs application with @akryum/ssr When I run npm run ssr:serve or npm run ssr:start everything functions properly. However, when attempting to utilize docker: version: '3.7' services: npm: build: context: ./ ...

Asynchronously download static images with the power of NextJS and TypeScript integration

I have a query regarding my website development using NextJS and TypeScript. The site features a showcase gallery and is completely static. Currently, the initial view shows thumbnails of images. When clicking on a thumbnail, the original image is display ...

Create a standalone 404 page using React Router that is completely isolated from any other components

Currently, I am collaborating with <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="dfadbabebcabbaadf2adb0aaabbaadf2bbb0b29fe9f1ebf1ed">[email protected]</a> and the code I am working on looks like this: index.tsx ...

What is the role-based menu item feature and routing in Angular 14?

My Angular App is running version 14. The header contains links for Register, Login, Add New Employee, List of Employees, Update Employee Profile, Employee Profile, Working Hours, and Logout. https://i.sstatic.net/M1len.png If a user with an Admin role l ...

Is it necessary for the React generic type prop to be an extension of another type

I have recently started using TypeScript and I am facing a confusion regarding passing generic types into my higher-order component (HOC). My objective is to pass the component props as a generic type in order to have the Component with those specific type ...

Employing a pair of interdependent v-select components to prevent any duplicate entries

I am currently working with two v-select boxes that share similar data. In my scenario, I extract attachments from an email and load them into an array. The issue I encountered is that the first select box should only allow the selection of one document, w ...

Detecting if a string is in sentence or title case with a typeguard

When setting the sameSite property of a cookie, it must be either Strict, Lax, or None. However, the package I'm using uses lowercase values for this attribute. Therefore, I need to adjust the first letter of the string: let sentenceCaseSameSite: &quo ...

Unspecified properties emerge post-Angular update

We recently consolidated multiple Angular 16 projects into one NX mono repository using Angular 17. Everything is functioning properly, EXCEPT we have noticed a peculiar change in behavior with our models. Previously, unset properties were simply not displ ...