Driver FixRecommendedSound, Wi-Fi or graphics acting up? Check drivers firstFind missing or outdated drivers fast.Check DriversOctober DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsPC HealthRecommendedCrashes, freezes, slowdowns? Check your PC nowSpot repairable issues before they interrupt work.Check PC×
Skip to content
World desk5 min

I Just Learned JS Custom Events (And When to Use Them)

A JavaScript custom event lets your code announce an application-defined occurrence to any listeners on a DOM element. Here is how to create and dispatch a CustomEvent, handle bubbling and cleanup, and decide when an event beats a direct call.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

A JavaScript custom event is an event your own code creates and sends to a DOM element so that any listeners attached to it can react. You make one with new CustomEvent(), attach its data through the detail property, and send it with dispatchEvent(). Use one when a component needs to announce that something happened and several parts of the page may care, without knowing in advance which parts those are.

What a custom event actually is

The browser fires built-in events such as click, input, and submit in response to user actions and page activity. A custom event uses the same machinery, but your application defines its name and decides when it fires. The name can be anything that describes the occurrence, such as cart-add or dialog-closed. Note that this is a browser DOM feature, not special syntax in the JavaScript language itself.

As an Amazon Associate I earn from qualifying purchases.

The CustomEvent interface, documented by MDN Web Docs, extends the basic Event interface with one extra property, detail. That property carries whatever data listeners need to know about the occurrence. If you do not need to pass data, a plain Event is enough.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Creating and dispatching a CustomEvent

The whole pattern takes four moves. Here is the sequence, with the code for each step:

  1. Pick a target and a type. The target is the EventTarget (usually a DOM element) that will send and receive the event. The type is a string such as "cart-add". Type strings are case-sensitive, so "Cart-Add" and "cart-add" are different events and a mismatch fails silently.

  2. Register a listener. Call addEventListener(type, handler) on the target. Unlike assigning to an on... property, addEventListener lets several handlers coexist on the same type, and it accepts options for capture and bubbling phases.

  3. Construct the event. Pass the type and an options object. If listeners need data, put it in detail. When you omit detail, it defaults to null.

    Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  4. Dispatch it. Call target.dispatchEvent(event). The browser then runs the normal event-processing rules for that target, including capture and, if you asked for it, bubbling.

const card = document.querySelector(".card");

card.addEventListener("cart-add", (event) => {
  console.log(event.detail.productId); // "sku-123"
});

card.dispatchEvent(new CustomEvent("cart-add", {
  detail: { productId: "sku-123" },
}));

Running this logs sku-123 to the console. The listener runs synchronously during the dispatchEvent() call, so code placed after that call runs only after every listener has finished.

Bubbling: why the default matters

Custom events do not bubble unless you say so. A dispatched event goes to its target and to any capture-phase listeners along the path, but it does not travel up to ancestor elements unless the event was created with bubbles: true. This is the setting you need when you want a single listener on a container to handle events from many children, which is event delegation.

const event = new CustomEvent("cart-add", {
  bubbles: true,
  detail: { productId: "sku-123" },
});
card.dispatchEvent(event);

Set propagation options on purpose, and write them down in the component’s documentation. A listener that works only because the event happens to bubble will break when someone moves the element or changes its wrapper.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

When to use a custom event

A custom event fits when a component or module has a meaningful occurrence to announce, when more than one listener may care, and when the emitter should not hold references to those listeners. Common cases include:

  • A product card announcing that an item was added to a cart, so a header counter, a mini-cart, and an analytics module can each respond.
  • A dialog announcing that it closed, so the page can restore focus or re-enable scrolling.
  • A custom picker or slider announcing a new selected value, so a form or a preview can update.

These cases are illustrations of the pattern, not measured results from any particular project.

When a direct function call is the better choice

Events add indirection, and indirection costs readability. If one specific piece of code asks another specific piece to do something, or needs a return value immediately, call the function directly. Events do not return values from listeners to the dispatcher, so a dispatch is a poor way to ask a question.

Situation Better choice Main tradeoff
One known caller needs a result right away Direct function call Caller and callee are directly connected
Something happened and any number of parts may react Custom event You must manage event names, target choice, listener cleanup, and propagation
Announcement needs no data new Event(type) Listeners cannot read a payload
Announcement carries application data new CustomEvent(type, { detail }) Payload is only as clear as the documented shape of detail

A useful test: if the sentence describing the code begins with “something happened,” use an event. If it begins with “do this” or “tell me this,” use a function call.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Removing listeners and avoiding leaks

If the listener’s lifetime is shorter than the element’s, remove it when that lifetime ends. Call removeEventListener() with the same type, the same function reference, and the same capture option you used when adding it. An anonymous arrow function passed to addEventListener cannot be removed later, so store it in a variable first.

function onClosed(event) {
  console.log(event.detail.reason);
}

dialog.addEventListener("dialog-closed", onClosed);
// later, when the listener should stop:
dialog.removeEventListener("dialog-closed", onClosed);
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Compatibility and limits

MDN describes CustomEvent as widely available and says it has been available across browsers since July 2015. Treat that as a broad summary. Older embedded browsers, legacy environments, and unusual hosts can differ, so check your own target list before relying on it.

MDN also notes one specific Firefox caveat. When a web extension content script tries to send an event with a non-string detail value to a page script, Firefox can raise a permission error. MDN suggests cloning the object before passing it. Keeping detail to plain strings, numbers, and simple objects avoids the question altogether.

A dispatched event is created by your code, not by the browser. A manually dispatched cart-add event does not represent a real click or keypress by a user, so do not treat it as proof that a user performed an action.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Common mistakes

  • Mismatched type strings. Because the type is case-sensitive, a typo produces no error. Log the event type inside the listener while debugging.
  • Listening on the wrong target. A listener on document will not see an event dispatched on a detached element that never joins the document tree.
  • Relying on accidental bubbling. Set bubbles explicitly whenever a parent is supposed to hear the event.
  • Undocumented payloads. Write down the keys and types in detail. Listeners written later will depend on that shape.

Practical checklist before you ship a custom event

  • The name describes something that already happened, in past tense or as a clear state change.
  • The target is the element that owns the occurrence.
  • Bubbling and cancelability are set on purpose, not left at defaults by accident.
  • detail is small, documented, and cloneable.
  • Every listener that can outlive its usefulness has a matching removeEventListener() call.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
Windows Errors? Fix Them Before They SpreadFree repair scan
Crashes, No Sound, or Screen Glitches?Free driver scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.