Multi-level Custom Context Menu Made Easy – ctxmenu.js

Category: Javascript , Menu & Navigation | January 21, 2026
Authornkappler
Last UpdateJanuary 21, 2026
LicenseMIT
Views314 views
Multi-level Custom Context Menu Made Easy – ctxmenu.js

ctxmenu.js is a lightweight yet customizable context menu library that provides relevant options and actions for your site’s content instead of relying on the default browser context menu.

You can specify custom context menus for different elements, use JavaScript functions or HTML links for interactive items, and create infinite nested submenus.

It’s fully customizable, has built-in dark mode support, and works great across devices like desktop and mobile.

How to use it:

1. Install and import the ctxmenu with NPM.

# NPM
$ npm install ctxmenu
import { ctxmenu } from "ctxmenu";

2. Or download the package and load the minified version of the ctxmenu.js library in the document.

<script src="ctxmenu.min.js"></script>

3. Define your menu items in a JS array as follows:

const myMenu = [
      // Menu 1 Header
      {
        text?: string | () => string,
        tooltip?: string | () => string,
        html?: string | () => string,
        element?: HTMLElement | () => HTMLElement,
        icon?: string | () => string,
        style?: string | () => string,
        events?: EventRegistry | () => EventRegistry,
        attributes?: Record<string, string> | () => Record<string, string>
      },
      // Menu 1 Item
      {
        // Standard props here
        action: (event: MouseEvent) => void,
        disabled?: boolean | () => boolean
      },
      // Divider
      { isDivider: true },
      // Menu 2 Header Here
      // Menu 2 Item
      {
        // Standard props here
        href: string | () => string,
        target?: string | () => string,
        disabled?: boolean | () => boolean
      },
      // Has sub menu
      {
        subMenu: [
          // sub menus here
        ]
      }
]

4. Attach the context menu to the element you specify.

ctxmenu.attach(".myElement", myMenu, {
  // configs
  onBeforeShow?: (menu: CTXMenu, event?: MouseEvent) => CTXMenu;
  onShow?: (dom: HTMLUListElement) => void;
  onBeforeHide?: (dom: Element) => void;
  onHide?: (dom: Element) => void;
  attributes?: Record<string, string>
})

5. More API methods.

// Update the context menu
ctxmenu.update(target: string, ctxmenu?: Array, beforeRender?: (menu: Array, event: MouseEvent) => Array)
// Delete the context menu from a container element
ctxmenu.delete(target: string)
// Show the context menu with a custom mouse event
ctxmenu.show(ctxmenu: Array, e: MouseEvent | HTMLElement)
// Hide the context menu
ctxmenu.hide()

Changelog:

v2.1.0 (01/21/2026)

  • Add Csp nonce support

v2.0.2 (02/12/2025)

  • bugfixes

v2.0.1 (01/27/2025)

  • bugfixes

v2.0.0 (01/03/2025)

  • refactor and bugfix

v1.7.0 (03/14/2024)

  • reworked lifecycle events
  • added possibility to customize via HTML attributes (class, id, name, data-attributes, etc.)

You Might Be Interested In:


Leave a Reply