useToast and useOverlay not working on prod, working fine on dev
So I've been struggling with nuxt ui for the past few days, I use the useToast and useOverlay composables and everything works fine on dev mode, but once I deploy my project they just wont do anything and I have no idea why. I tried both ssr and ssg mode but it doesn't work. I don't understand what I'm doing wrong here.
I installed nuxt UI 4.0.0 that just came out, but that didn't change anything
For instance one of my useToast is used in a pinia store :
And my app.vue is :
3 Replies
Hi @Goromi. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:
----------------------
Your usage of
You are correctly wrapping your app with
Using
- Move Toast/Overlay Calls to Components:
Instead of calling
If you need to trigger a toast from a store, consider using a global event bus or a callback pattern to notify your component to show the toast. 4. Production Differences
The reason it works in development but not in production is likely due to differences in hydration and context setup between dev and prod builds. Production builds are stricter about context boundaries. Summary:
- You are using
useToast
and useOverlay
in development is correct, but if they do not work in production, there are a few important caveats and requirements from the Nuxt UI documentation that you should check:
1. UApp WrappingYou are correctly wrapping your app with
<UApp>
, which is required for both useToast
and useOverlay
to function, as they rely on providers set up by this component. This is confirmed in the docs:Make sure to wrap your app with theToast documentation 2. Pinia Store ContextApp
component which uses ourToaster
component which uses theToastProvider
component from Reka UI.
Using
useToast
(or any composable that relies on Vue's inject/provide system) inside a Pinia store can be problematic, especially in production or SSR/SSG, because Pinia stores are not always created within the same Vue context as your app. The Nuxt UI documentation specifically warns about this for overlays, but the same principle applies to toasts:
When opening overlays programmatically (e.g. modals, slideovers, etc), the overlay component can only access injected values from the component containingProvide/Inject caveats This means that callingUApp
(typicallyapp.vue
or layout components). This is because overlays are mounted outside of the page context by theUApp
component.
useToast()
inside a Pinia store (which is not a Vue component) may not have access to the correct injection context, especially in production builds.
3. Recommended Solution- Move Toast/Overlay Calls to Components:
Instead of calling
useToast
or useOverlay
inside your Pinia store, emit an event or call a callback from your store, and handle the toast/overlay logic in a Vue component that is a child of <UApp>
. This ensures the composables have access to the correct context.
- Pass Data via Props or Events:If you need to trigger a toast from a store, consider using a global event bus or a callback pattern to notify your component to show the toast. 4. Production Differences
The reason it works in development but not in production is likely due to differences in hydration and context setup between dev and prod builds. Production builds are stricter about context boundaries. Summary:
- You are using
<UApp>
correctly.
- Do not use useToast
or useOverlay
inside Pinia stores or outside of Vue components that are direct children of <UApp>
.
- Move your toast logic into components, and trigger them from your store via events or callbacks.
For more details, see the official documentation on useToast and the caveats for useOverlay.
If you need an example of how to restructure your code, let me know!
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@379253669792841738> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
It doesn't work even if I put useToast in a component :