8000 Nuxt instance is unavailable after `await` in nuxt plugin · Issue #30796 · nuxt/nuxt · GitHub
[go: up one dir, main page]

Skip to content
Nuxt instance is unavailable after await in nuxt plugin #30796
@tobiasdcl

Description

@tobiasdcl

Environment

default nuxt stackblitz template

npx nuxi info
Working directory: /home/projects/xoriwnmyzv.github                                                                nuxi 09:27:51
Nuxt project info:                                                                                                 nuxi 09:27:51

------------------------------
- Operating System: Linux
- Node Version:     v18.20.3
- Nuxt Version:     3.15.3
- CLI Version:      3.20.0
- Nitro Version:    2.10.4
- Package Manager:  npm@10.2.3
- Builder:          -
- User Config:      compatibilityDate, devtools
- Runtime Modules:  -
- Build Modules:    -
------------------------------

Reproduction

https://stackblitz.com/edit/github-az9lz6we?file=plugins%2FreproCaller.ts

Describe the bug

Hey there,
first of all great work! ❤️

I think I found a bug that results in loosing the nuxt context after calling an async function in a nuxt plugin - I was able to boil it down to a minimal reproduction and attached the source code as well as a link to stackblitz

I am aware of the limitations but I think this use case should be supported according to the docs as useNuxtApp is called within defineNuxtPlugin

you cannot use await before calling a composable, except within <script setup> blocks, within the setup function of a component declared with defineNuxtComponent, in defineNuxtPlugin or in defineNuxtRouteMiddleware, where we perform a transform to keep the synchronous context even after the await. (source)

Please note that he issue can be mitigated by adding an additional await Promise.resolve() as described in the the reproduction - hope that helps!

Thanks 🙌

Additional context

also pasting the relevant reproduction code here to make it easier to search for:

plugin/repro.ts

export default defineNuxtPlugin({
  name: 'repro',
  async setup() {
    console.log('Hello from repro plugin');

    async function functionThatLoosesContext() {
        // when we enter the function we still have our context

        console.log('calling useNuxtApp() => still got the context');
        useNuxtApp();

        // this will cause us to loose the nuxt context IF the calling plugin as no other await before calling this function
        await Promise.resolve();

        /**
         * [nuxt] A composable that requires access to the Nuxt instance was called outside of a plugin, Nuxt hook, Nuxt middleware, or Vue setup function.
         */
        console.log('calling useNuxtApp() => 💥 BOOM 💥');
        useNuxtApp();
    }

    return {
        provide: {
            functionThatLoosesContext,
        },
      };
  },
});

plugin/reproCaller.ts

export default defineNuxtPlugin({
  name: 'reproCaller',
  dependsOn: ['repro'],
  async setup() {
    console.log('[reproCaller] start');

    /**
     * Uncommenting the following line will mitigate the loss of the nuxt context
     */
    //await Promise.resolve();

    await useNuxtApp().$functionThatLoosesContext();

    console.log('[reproCaller] end');
  },
});

Logs

Hello from repro plugin
[reproCaller] start
calling useNuxtApp() => still got the context
calling useNuxtApp() => 💥 BOOM 💥



500
[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`.

at Object.functionThatLoosesContext (./plugins/repro.ts:11:43)
at async setup (./plugins/reproCaller.ts:8:140)
at async Object.callAsync (./node_modules/unctx/dist/index.mjs:91:16)
at async applyPlugin (./node_modules/nuxt/dist/app/nuxt.js:142:25)
at async executePlugin (./node_modules/nuxt/dist/app/nuxt.js:179:9)
at async applyPlugins (./node_modules/nuxt/dist/app/nuxt.js:193:5)
at async createNuxtAppServer (./node_modules/nuxt/dist/app/entry.js:15:7)
at async 𝐝𝐞𝐟𝐚𝐮𝐥𝐭 (./node_modules/@nuxt/vite-builder/dist/runtime/vite-node.mjs:49:18)
at async Object.renderToString (./node_modules/vue-bundle-renderer/dist/runtime.mjs:199:19)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0