vue.jsnuxt.jsnuxt-middleware

A composable that requires access to the Nuxt instance was called outside of a plugin, Nuxt hook, Nuxt middleware, or Vue setup function


I'm getting this error when I use useNewSession.ts composable in my Nuxt middleware.

[nuxt] A composable that requires access to the Nuxt instance was called outside of a plugin, Nuxt hook, Nuxt middleware, or Vue setup function. This is probably not a Nuxt bug. Find out more at https://nuxt.com/docs/guide/concepts/auto-imports#vue-and-nuxt-composables.

This is my /middleware/org.ts (Just refreshing the bearer token, and making an API call and setting the cookie)

export default defineNuxtRouteMiddleware(async () => {
  const newSession = await useNewSession() // <- This is the problem, but the code block is executed
  const accessToken = newSession.access_token

  const { data, error } = await useFetch('/api/organization', {
    headers: {
      authorization: `Bearer ${accessToken}`
    }
  })

  if (error.value) {
    throw error
  }

  // Set the organization data into a cookie
  const organizationCookie = useCookie('organization')
  organizationCookie.value = JSON.stringify(data.value)

})

This is the composable I am using /composables/useNewSession.ts. It just refreshes the session from supabase plugin.

export default async function() {
  const supabase = useNuxtApp().$supabase
  const { data, error } = await supabase.auth.refreshSession()

  if (error || !data.session) {
    navigateTo('/login')
    const toast = useToast()
    toast.add({
      title: 'Session error',
      description: error?.message,
      color: 'error',
    })
    throw error
  }

  return data.session
}

This is the code I am defining middleware in page meta

<script lang="ts">
export default {
  setup() {
    definePageMeta({
      middleware: ["auth", "org"],
      layout: 'dashboard'
    })
  }
}
</script>

The error says I am using Nuxt composable outside of Nuxt middleware. But, I am using inside defineNuxtRouteMiddleware. Not sure if I am doing something wrong here. Any suggestions, tips or help are greatly appreciated. Thank you!!


Solution

  • I was able to solve this by wrapping the logic within an import.meta.client if statement. Composables are available only on the client side, hence it couldn't resolve it on SSR.

    This worked for me.

    export default defineNuxtRouteMiddleware(async () => {
    
      // Do this only on the client side
      if (import.meta.client) {
        const newSession = await useNewSession()
        const accessToken = newSession.access_token
    
        const { data, error } = await useFetch('/api/organization', {
          headers: {
            'Authorization': `Bearer ${accessToken}`
          },
        })
    
        if (error.value) {
          throw error
        }
    
        const organizationCookie = useCookie('af-organization')
        organizationCookie.value = JSON.stringify(data.value)
      }
    })