N
Nuxt4mo ago
Omnislash

Custom hook to emit/broadcast message

Hello Kapa I want to emit/broadcast a message to all my components when my user click on a specific button of a page. I found this : https://nuxt.com/docs/guide/going-further/events, but it looks like it's only with pre-defined hooks that happen at specific moments. How can I broadcast just a very simple event that all my components can listen to ? thanks 🙂
17 Replies
kapa.ai
kapa.ai4mo ago
Hi @Omnislash. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- Absolutely! You can create and broadcast custom events in Nuxt using its built-in event system, which is powered by hookable. You are not limited to pre-defined hooks—Nuxt allows you to define and emit your own custom events that any part of your app can listen to. How to broadcast a custom event: 1. Listen for the event in your components: In any component (or plugin), use the hook method from the Nuxt app context to listen for your custom event:
const nuxtApp = useNuxtApp()

nuxtApp.hook('my:custom:event', (payload) => {
// Handle the event
console.log('Received message:', payload)
})

const nuxtApp = useNuxtApp()

nuxtApp.hook('my:custom:event', (payload) => {
// Handle the event
console.log('Received message:', payload)
})

2. Emit (broadcast) the event: When your user clicks the button, call callHook with your custom event name and any payload you want to send:
const nuxtApp = useNuxtApp()

function onButtonClick() {
nuxtApp.callHook('my:custom:event', { message: 'Hello from the button!' })
}

const nuxtApp = useNuxtApp()

function onButtonClick() {
nuxtApp.callHook('my:custom:event', { message: 'Hello from the button!' })
}

All components that have registered a listener for 'my:custom:event' will receive the payload when you emit it. This is a simple and effective way to broadcast messages across your app, fully supported by Nuxt’s event system. For more details and examples, see the official Nuxt documentation on Events and how to create custom events and listeners in your app. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai4mo ago
<@305772639438503936> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Omnislash
OmnislashOP4mo ago
@kapa.ai If I try that in typescript, it says : Argument of type '"custom"' is not assignable to parameter of type 'HookKeys<RuntimeNuxtHooks>'
kapa.ai
kapa.ai4mo ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- You're correct—when using TypeScript, Nuxt's event system only recognizes hook names that are defined in its types. If you try to use a custom event name (like 'custom' or 'my:custom:event'), TypeScript will complain because it's not part of the built-in RuntimeNuxtHooks type. How to fix this: You need to augment the Nuxt types to declare your custom hook. The Nuxt documentation provides an example of how to do this:
import { HookResult } from "@nuxt/schema";

declare module '#app' {
interface RuntimeNuxtHooks {
'my:custom:event': (payload: { message: string }) => HookResult
}
}
import { HookResult } from "@nuxt/schema";

declare module '#app' {
interface RuntimeNuxtHooks {
'my:custom:event': (payload: { message: string }) => HookResult
}
}
Add this code to a .d.ts file in your project (for example, types/nuxt-hooks.d.ts). This tells TypeScript about your custom event, so you can use it safely with nuxtApp.hook and nuxtApp.callHook without type errors. Reference:
See the Augmenting Types section in the Nuxt Events documentation for more details and examples. Once you've augmented the types, your code will be type-safe and TypeScript will recognize your custom event names. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai4mo ago
<@305772639438503936> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Omnislash
OmnislashOP4mo ago
@kapa.ai the folder types should be in folder app or in the root ?
kapa.ai
kapa.ai4mo ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- The knowledge sources indicate that the recommended location for your custom types folder is the root of your project, not inside the app folder. For example, in the new Nuxt directory structure, the types/ folder is shown at the root level alongside app/, server/, and other top-level directories:
.output/
.nuxt/
app/
...
types/
server/
...
nuxt.config.ts
.output/
.nuxt/
app/
...
types/
server/
...
nuxt.config.ts
This structure helps ensure that your type definitions are available globally and are properly picked up by TypeScript and Nuxt's tooling. There is no mention in the official documentation of placing the types folder inside the app directory, and examples from both the documentation and community sources show it at the root level New Directory Structure Stack Overflow Example. So, you should place your types folder in the root of your Nuxt project. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai4mo ago
<@305772639438503936> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
ChristopherK
ChristopherK3mo ago
Has somebody figured out, how to fix the ts-error 'Argument of type '"custom"' is not assignable to parameter of type 'HookKeys<RuntimeNuxtHooks>'' ? I created a d.ts file exactly like kapa.ai suggested. @kapa.ai Is there any new fix for this?
kapa.ai
kapa.ai3mo ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- Based on the available knowledge sources, the recommended way to fix the TypeScript error
Argument of type '"custom"' is not assignable to parameter of type 'HookKeys<RuntimeNuxtHooks>'
is to augment the Nuxt types by declaring your custom hook in a .d.ts file, as described in the Nuxt documentation:
import { HookResult } from "@nuxt/schema";

declare module '#app' {
interface RuntimeNuxtHooks {
'my:custom:event': (payload: { message: string }) => HookResult
}
}
import { HookResult } from "@nuxt/schema";

declare module '#app' {
interface RuntimeNuxtHooks {
'my:custom:event': (payload: { message: string }) => HookResult
}
}
This file should be placed in the types/ folder at the root of your project. Make sure your tsconfig.json includes this folder (e.g., "include": ["types/**/*.d.ts"]) so TypeScript picks up the augmentation Stack Overflow Example. If you have already done this and are still seeing the error, the knowledge sources do not mention any newer or alternative fixes. There is no explicit information about additional steps or recent changes that would affect this process. If the error persists, it may be due to IDE caching or misconfiguration—try restarting your IDE and ensuring your type definitions are included correctly. If you are using JetBrains IDEs (like WebStorm or PhpStorm), be aware of a known bug where custom global properties or hooks may not be recognized, even if your type augmentation is correct. In such cases, the types may work as expected in VSCode JetBrains IDE bug reference. In summary:
- The documented fix is to augment the types as shown above. - No newer or alternative fix is mentioned in the knowledge sources. - If the error persists, check your IDE and TypeScript configuration, and consider IDE-specific issues. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai3mo ago
<@1033989726300024842> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Omnislash
OmnislashOP3mo ago
The interface did the trick for me. Didn't touch any .d.ts
ChristopherK
ChristopherK3mo ago
And where did you put the interface?
Omnislash
OmnislashOP3mo ago
https://github.com/ribbityfrog/hotpot/blob/main/app%2Futils%2Fhooks.ts In utils so it's autoloaded Probably not the cleanest but enough for my needs, but didn't really see any "standard" method Then I call it here in a composable : https://github.com/ribbityfrog/hotpot/blob/main/app%2Fcomposables%2Ftheming.ts#L189-L190
ChristopherK
ChristopherK3mo ago
Tried that, but now get this error: Invalid module name in augmentation, module '#app' cannot be found.ts(2664) Your project is using nuxt4, i'm on 3.17.5 and we don't want to upgrade yet.
Omnislash
OmnislashOP3mo ago
Just compatibility, the project itself is 3.17.5 too I reckon
dwol
dwol3mo ago
i have this in app/types/nuxt-hooks.d.ts
import type { HookResult } from '@nuxt/schema'

declare module '#app' {
interface RuntimeNuxtHooks {
'app:user:permissions': (permission: NotificationPermission) => HookResult
}
interface NuxtHooks {
'app:user:permissions': (permission: NotificationPermission) => HookResult
}
}
import type { HookResult } from '@nuxt/schema'

declare module '#app' {
interface RuntimeNuxtHooks {
'app:user:permissions': (permission: NotificationPermission) => HookResult
}
interface NuxtHooks {
'app:user:permissions': (permission: NotificationPermission) => HookResult
}
}

Did you find this page helpful?