# How to Implement Keyboard Shortcuts Like Alt+Shift+M in Chrome Extensions: A Markdown Here Deep Dive

> Learn how Markdown Here implements AltShiftM keyboard shortcuts declaratively in Chrome extensions. Discover the power of the manifest commands section for efficient extension control.

- Repository: [Adam Pritchard/markdown-here](https://github.com/adam-p/markdown-here)
- Tags: deep-dive
- Published: 2026-03-05

---

**The Alt+Shift+M shortcut in Markdown Here is implemented declaratively through the Chrome extension manifest's `commands` section using the special `_execute_action` identifier, which automatically binds the keystroke to the extension's primary action handler without hardcoding key detection in JavaScript.**

Keyboard shortcuts are essential for productivity-focused browser extensions like Markdown Here, allowing users to toggle Markdown rendering instantly. In the `adam-p/markdown-here` repository, the Alt+Shift+M shortcut demonstrates the modern approach to implementing Chrome extension keyboard shortcuts through manifest declarations rather than manual key event listeners.

## How the Alt+Shift+M Shortcut Works

The implementation follows a four-step pipeline: declaration in the manifest, automatic routing by the browser, handling in the background script, and finally execution in the content script. This architecture separates concerns between the browser's shortcut management and the extension's business logic.

## Step 1: Declaring the Keyboard Shortcut in the Manifest

### The _execute_action Command

In [`src/manifest.json`](https://github.com/adam-p/markdown-here/blob/main/src/manifest.json), the shortcut is defined under the `commands` section using the reserved `_execute_action` identifier. This special key tells Chrome and Firefox to treat this command as the extension's primary action, automatically triggering the same handler as a toolbar button click.

```json
"commands": {
  "_execute_action": {
    "suggested_key": {
      "default": "Alt+Shift+M",
      "mac": "Alt+Shift+M"
    }
  }
}

```

The `suggested_key` field specifies the default binding, which users can customize through their browser's extension shortcut settings. By using `_execute_action`, the extension avoids hardcoding keyboard event listeners and leverages the browser's native shortcut management.

## Step 2: Handling the Shortcut in the Background Script

When the user presses Alt+Shift+M, the browser automatically routes the command to the `chrome.action.onClicked` listener in [`src/chrome/backgroundscript.js`](https://github.com/adam-p/markdown-here/blob/main/src/chrome/backgroundscript.js). This listener handles both toolbar button clicks and keyboard shortcuts uniformly.

```javascript
// Handles both toolbar clicks and the keyboard shortcut.
chrome.action.onClicked.addListener(async function(tab) {
  await handleActionClick(tab);
});

```

The `handleActionClick` function performs two critical operations: it injects the content scripts into the current tab if they aren't already present, and it sends a `button-click` message to the page-side code. This message triggers the actual Markdown toggle logic, keeping the background script focused on orchestration rather than rendering.

## Step 3: Displaying the Current Shortcut in the Options Page

To keep the documentation synchronized with the actual binding, [`src/common/options.js`](https://github.com/adam-p/markdown-here/blob/main/src/common/options.js) queries the browser's command API to retrieve the currently configured shortcut. This ensures that if the user customizes the key combination through browser settings, the options page displays the correct value.

```javascript
chrome.commands.getAll().then(commands => {
  const shortcut = commands[0].shortcut;
  if (shortcut) {
    document.querySelectorAll('.hotkey-current')
      .forEach(el => el.textContent = shortcut);
  }
});

```

This approach demonstrates best practices for extension UX: never hardcode shortcut strings in the UI, always fetch the current configuration from the browser's API.

## Step 4: Toggling Markdown Rendering

Once the content script receives the `button-click` message from the background script, the core logic in [`src/common/markdown-here.js`](https://github.com/adam-p/markdown-here/blob/main/src/common/markdown-here.js) executes the toggle. This module maintains state about whether the current content is rendered Markdown or raw text, then performs the conversion or reversion accordingly.

The toggle routine checks the document's current state, extracts Markdown from the DOM or restores the original text, and updates the editor's content without reloading the page. This file contains the actual rendering engine that interprets the Markdown syntax and generates the HTML output.

## Summary

- **Manifest declaration**: The Alt+Shift+M shortcut is defined in [`src/manifest.json`](https://github.com/adam-p/markdown-here/blob/main/src/manifest.json) using the `_execute_action` command identifier, which binds it to the extension's primary action.
- **Automatic routing**: Chrome and Firefox automatically route the shortcut to the `chrome.action.onClicked` listener without requiring manual key event detection.
- **Background handling**: [`src/chrome/backgroundscript.js`](https://github.com/adam-p/markdown-here/blob/main/src/chrome/backgroundscript.js) processes the action by injecting content scripts and sending a `button-click` message to the active tab.
- **Dynamic UI**: [`src/common/options.js`](https://github.com/adam-p/markdown-here/blob/main/src/common/options.js) uses `chrome.commands.getAll()` to display the current shortcut in the options page, ensuring UI consistency with user customizations.
- **Core toggle**: The actual Markdown rendering toggle occurs in [`src/common/markdown-here.js`](https://github.com/adam-p/markdown-here/blob/main/src/common/markdown-here.js) when it receives the message from the background script.

## Frequently Asked Questions

### Why use `_execute_action` instead of a custom command name?

Using the reserved `_execute_action` identifier allows the browser to automatically handle both toolbar button clicks and keyboard shortcuts through the same `chrome.action.onClicked` listener. This eliminates the need to write separate key event listeners or command handling logic, reducing code complexity and ensuring consistent behavior across interaction methods.

### Can users customize the Alt+Shift+M shortcut?

Yes, users can customize the shortcut through their browser's extension keyboard shortcut settings. The extension reads the actual configured key combination using `chrome.commands.getAll()` in [`src/common/options.js`](https://github.com/adam-p/markdown-here/blob/main/src/common/options.js), ensuring the options page always displays the current binding rather than a hardcoded string.

### How does the background script communicate with the content script?

When the shortcut is triggered, the background script in [`src/chrome/backgroundscript.js`](https://github.com/adam-p/markdown-here/blob/main/src/chrome/backgroundscript.js) first ensures the content scripts are injected into the active tab, then sends a message with the action `button-click` using Chrome's messaging API. The content script listens for this message and triggers the toggle logic in [`src/common/markdown-here.js`](https://github.com/adam-p/markdown-here/blob/main/src/common/markdown-here.js).

### Is the shortcut handling different between Chrome and Firefox?

No, the implementation uses the WebExtensions API (`chrome.commands` and `chrome.action`), which is supported by both Chrome and Firefox with compatible manifest formats. The `_execute_action` command works consistently across both browsers, though Firefox may use `browser.action` instead of `chrome.action` in some contexts, the underlying behavior remains the same.