-
-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Description
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 withdefineNuxtComponent
, indefineNuxtPlugin
or indefineNuxtRouteMiddleware
, 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)