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

Nuxt Instance error on try to integrate Nuxt Auth and TanStack. #273

Closed
guilherme-codes opened this issue Nov 9, 2024 · 5 comments · Fixed by #278
Closed

Nuxt Instance error on try to integrate Nuxt Auth and TanStack. #273

guilherme-codes opened this issue Nov 9, 2024 · 5 comments · Fixed by #278

Comments

@guilherme-codes
Copy link
Contributor

guilherme-codes commented Nov 9, 2024

I'm using TanStack to fetch and cache my data, so I created a plugin to manage it. After three retries I'd like to redirect the user to the auth path and clear the session.
The problem is that I'm receiving the famous "A composable that requires access to the Nuxt instance was called outside of a plugin..." error.

I tried to use nuxtApp.runWithContext(() => {}) to manage it but unfortunately doesn't work.

Is there any way to fix it @atinux?? I'll place my code below to make it easy to understand.

import type {
  DehydratedState,
  VueQueryPluginOptions,
} from '@tanstack/vue-query';

import {
  VueQueryPlugin,
  QueryClient,
  hydrate,
  dehydrate,
  QueryCache,
} from '@tanstack/vue-query';

import { useState } from '#app';

export default defineNuxtPlugin((nuxt) => {
  const { clear } = useUserSession();

  const config = useRuntimeConfig();
  const vueQueryState = useState<DehydratedState | null>('vue-query');
  const nuxtApp = useNuxtApp();

  const queryClient = new QueryClient({
    defaultOptions: {
      queries: {
        staleTime: 3000,
        retry: (failureCount, error) => {
          if (failureCount < 3) {
            return true;
          }

          redirectIfUnauthorized(error);
          return false;
        },
      },
    },
    queryCache: new QueryCache({
      onError: (error) => redirectIfUnauthorized(error),
    }),
  });

  const options: VueQueryPluginOptions = { queryClient };

  nuxt.vueApp.use(VueQueryPlugin, options);

  if (import.meta.server) {
    nuxt.hooks.hook('app:rendered', () => {
      vueQueryState.value = dehydrate(queryClient);
    });
  }

  if (import.meta.client) {
    nuxt.hooks.hook('app:created', () => {
      hydrate(queryClient, vueQueryState.value);
    });
  }

  const redirectIfUnauthorized = (error: unknown) => {
    const response = error
    const authPath = config.public.authPath as string;
  
    if (response?.status === 401) {
      nuxtApp.runWithContext(() => {
        navigateTo(authPath, { external: true })
        clear();  // it is throwing the error
      })
    }
  };
  
});
@guilherme-codes guilherme-codes changed the title Nuxt Instance error on TanStack integration. Nuxt Instance error on try to integrate Nuxt Auth and TanStack. Nov 11, 2024
atinux added a commit that referenced this issue Nov 11, 2024
@atinux
Copy link
Owner

atinux commented Nov 11, 2024

Hi @guilherme-codes

Can you please try with this version and confirm that the fix works?

pnpm add https://pkg.pr.new/atinux/nuxt-auth-utils@278

Then start again your development server and try to reproduce your issue.

@guilherme-codes
Copy link
Contributor Author

It works well. Thanks

atinux added a commit that referenced this issue Nov 11, 2024
@atinux
Copy link
Owner

atinux commented Nov 11, 2024

You can now use https://github.com/atinux/nuxt-auth-utils/releases/tag/v0.5.3 :)

@sandros94
Copy link
Contributor

@atinux I'm curious (on a module author's perspective) to understand something in your fix (065c54d)

What was causing it? Was it the fact that fetch and clear where defined outside useUserSession?

@atinux
Copy link
Owner

atinux commented Nov 12, 2024

The main issue was calling useSessionState().value = {} after an await, which itself use useState() that depends on the current instance (see here)

The fix was to use the variables defined before any await in order to work properly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants