Files
electron/docs/tutorial/application-menu.md
T
Samuel AttardandClaude ad3a896a52 build: check the formatting of docs code blocks with oxfmt (#54140)
* build: check the formatting of docs code blocks with oxfmt

lint-roller 4 splits the old `lint-roller-markdown-standard` into an
oxlint half and an oxfmt half. This wires up the second one:
`lint:fmt-in-markdown` runs `lint-roller-markdown-oxfmt` over docs/ as
part of `lint:docs`, using docs/.oxfmtrc.json, which matches the repo's
.oxfmtrc.json except that docs snippets keep their semicolon-free style.
`--fix` writes the formatted blocks back, and a block can opt out with
`@noformat` in its info string.

* docs: format code blocks with oxfmt

Result of `lint-roller-markdown-oxfmt --fix` with docs/.oxfmtrc.json, plus
the @ts-expect-error line anchors (and one Docusaurus highlight marker)
that moved with the reformat. The Babel output sample in the ESM guide and
the two excerpts of repo source in creating-api.md are marked @noformat,
and the contentTracing example passes an async callback instead of
wrapping an IIFE so that it does not need a leading semicolon.

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-09-21 00:18:37 -07:00

5.3 KiB

title, description, slug, hide_title
title description slug hide_title
Application Menu Customize the main application menu for your Electron app application-menu true

Application Menu

Each Electron app has a single top-level application menu.

  • On macOS, this menu is shown in the system menu bar.
  • On Windows and Linux, this menu is shown at the top of each BaseWindow.

Building application menus

The application menu can be set by passing a Menu instance into the Menu.setApplicationMenu static function.

When building an application menu in Electron, each top-level array menu item must be a submenu.

Electron will set a default menu for your app if this API is never called. Below is an example of that default menu being created manually using shorthand MenuItem roles.

const { shell } = require('electron/common')
const { app, Menu } = require('electron/main')

const isMac = process.platform === 'darwin'
const template = [
  // { role: 'appMenu' }
  ...(isMac
    ? [
        {
          label: app.name,
          submenu: [
            { role: 'about' },
            { type: 'separator' },
            { role: 'services' },
            { type: 'separator' },
            { role: 'hide' },
            { role: 'hideOthers' },
            { role: 'unhide' },
            { type: 'separator' },
            { role: 'quit' }
          ]
        }
      ]
    : []),
  // { role: 'fileMenu' }
  {
    label: 'File',
    submenu: [isMac ? { role: 'close' } : { role: 'quit' }]
  },
  // { role: 'editMenu' }
  {
    label: 'Edit',
    submenu: [
      { role: 'undo' },
      { role: 'redo' },
      { type: 'separator' },
      { role: 'cut' },
      { role: 'copy' },
      { role: 'paste' },
      ...(isMac
        ? [
            { role: 'pasteAndMatchStyle' },
            { role: 'delete' },
            { role: 'selectAll' },
            { type: 'separator' },
            {
              label: 'Speech',
              submenu: [{ role: 'startSpeaking' }, { role: 'stopSpeaking' }]
            }
          ]
        : [{ role: 'delete' }, { type: 'separator' }, { role: 'selectAll' }])
    ]
  },
  // { role: 'viewMenu' }
  {
    label: 'View',
    submenu: [
      { role: 'reload' },
      { role: 'forceReload' },
      { role: 'toggleDevTools' },
      { type: 'separator' },
      { role: 'resetZoom' },
      { role: 'zoomIn' },
      { role: 'zoomOut' },
      { type: 'separator' },
      { role: 'togglefullscreen' }
    ]
  },
  // { role: 'windowMenu' }
  {
    label: 'Window',
    submenu: [
      { role: 'minimize' },
      { role: 'zoom' },
      ...(isMac
        ? [{ type: 'separator' }, { role: 'front' }, { type: 'separator' }, { role: 'window' }]
        : [{ role: 'close' }])
    ]
  },
  {
    role: 'help',
    submenu: [
      {
        label: 'Learn More',
        click: async () => {
          const { shell } = require('electron')
          await shell.openExternal('https://electronjs.org')
        }
      }
    ]
  }
]

const menu = Menu.buildFromTemplate(template)
Menu.setApplicationMenu(menu)

Important

On macOS, the first submenu of the application menu will always have your application's name as its label. In general, you can populate this submenu by conditionally adding a menu item with the appMenu role.

Tip

For additional descriptions of available roles, see the MenuItem roles section of the general Menus guide.

Using standard OS menu roles

Defining each submenu explicitly can get very verbose. If you want to re-use default submenus in your app, you can use various submenu-related roles provided by Electron.

const { shell } = require('electron/common')
const { app, Menu } = require('electron/main')

const template = [
  ...(process.platform === 'darwin' ? [{ role: 'appMenu' }] : []),
  { role: 'fileMenu' },
  { role: 'editMenu' },
  { role: 'viewMenu' },
  { role: 'windowMenu' },
  {
    role: 'help',
    submenu: [
      {
        label: 'Learn More',
        click: async () => {
          const { shell } = require('electron')
          await shell.openExternal('https://electronjs.org')
        }
      }
    ]
  }
]

const menu = Menu.buildFromTemplate(template)
Menu.setApplicationMenu(menu)

Note

On macOS, the help role defines a top-level Help submenu that has a search bar for other menu items. It requires items to be added to its submenu to function.

Setting window-specific application menus Linux Windows

Since the root application menu exists on each BaseWindow on Windows and Linux, you can override it with a window-specific Menu instance via the win.setMenu method.

const { BrowserWindow, Menu } = require('electron/main')

const win = new BrowserWindow()
const menu = Menu.buildFromTemplate([
  {
    label: 'my custom menu',
    submenu: [{ role: 'copy' }, { role: 'paste' }]
  }
])
win.setMenu(menu)

Tip

You can remove a specific window's application menu by calling the win.removeMenu API.