Keyboard Shortcuts in Firefox Extensions: A Complete Guide
Good keyboard support separates a great extension from a mediocre one. Here's everything you need to know.
manifest.json Commands
For global keyboard shortcuts (accessible even when the extension isn't focused):
{
"commands": {
"_execute_action": {
"suggested_key": {
"default": "Ctrl+Shift+W"
},
"description": "Open Weather & Clock Dashboard"
},
"toggle-theme": {
"suggested_key": {
"default": "Ctrl+Shift+D"
},
"description": "Toggle dark/light mode"
}
}
}
Available modifiers: Ctrl, Alt, Shift, MacCtrl (Mac Cmd key)
Note: Ctrl+Alt+* combinations are blocked on Windows. Use Ctrl+Shift+* for cross-platform shortcuts.
Listening for Commands in Background
browser.commands.onCommand.addListener((command) => {
switch (command) {
case 'toggle-theme':
toggleTheme();
break;
// other commands...
}
});
In-Page Keyboard Navigation
For shortcuts within your new tab page:
document.addEventListener('keydown', e => {
// Don't intercept when user is typing
if (isTypingContext()) return;
switch (e.key) {
case '/':
e.preventDefault();
document.getElementById('search-input').focus();
break;
case 'Escape':
document.activeElement.blur();
break;
case 'd':
if (e.ctrlKey) break; // Don't intercept Ctrl+D (bookmark)
toggleTheme();
break;
}
});
function isTypingContext() {
const tag = document.activeElement.tagName;
return tag === 'INPUT' || tag === 'TEXTAREA' || document.activeElement.isContentEditable;
}
Focus Search on Any Key
A common new tab pattern — pressing any letter key jumps to search:
document.addEventListener('keydown', e => {
if (isTypingContext()) return;
if (e.ctrlKey || e.metaKey || e.altKey) return;
if (e.key.length !== 1) return;
const searchInput = document.getElementById('search-input');
searchInput.focus();
// Don't preventDefault — let the character go into the search box
});
Displaying Keyboard Shortcuts
Show shortcuts in a help overlay:
const SHORTCUTS = [
{ key: '/', description: 'Focus search' },
{ key: 'Esc', description: 'Clear focus' },
{ key: 'd', description: 'Toggle dark mode' },
{ key: '?', description: 'Show this help' },
];
document.addEventListener('keydown', e => {
if (isTypingContext()) return;
if (e.key === '?') {
toggleHelpOverlay();
}
});
Getting the User's Assigned Shortcut
Users can reassign shortcuts in Firefox's extension manager. Always show the actual assigned shortcut, not a hardcoded string:
async function getShortcutForCommand(commandName) {
const commands = await browser.commands.getAll();
const cmd = commands.find(c => c.name === commandName);
return cmd?.shortcut || 'unassigned';
}
// Display in settings UI
const shortcut = await getShortcutForCommand('toggle-theme');
document.getElementById('shortcut-display').textContent = shortcut;
Accessibility: ARIA Keyboard Patterns
For custom widget keyboard navigation, follow ARIA authoring practices:
// Radio group keyboard navigation
function handleRadioKeydown(e, items) {
const currentIndex = items.indexOf(document.activeElement);
let newIndex;
switch (e.key) {
case 'ArrowDown':
case 'ArrowRight':
newIndex = (currentIndex + 1) % items.length;
break;
case 'ArrowUp':
case 'ArrowLeft':
newIndex = (currentIndex - 1 + items.length) % items.length;
break;
default:
return;
}
e.preventDefault();
items[newIndex].focus();
items[newIndex].click();
}
Common Pitfalls
-
Don't override browser shortcuts —
Ctrl+T,Ctrl+W,Ctrl+N,Ctrl+L,F5are hands-off -
Test on both Mac and Windows — Mac users use
Cmdwhere Windows usesCtrl - Remember sticky keys — some users navigate with keyboard only; test Tab/Shift+Tab flow
-
Clear focus indicators —
:focus-visibleis mandatory for keyboard users
/* Good focus indicator */
:focus-visible {
outline: 2px solid var(--accent-color);
outline-offset: 2px;
}
/* Never do this */
* { outline: none; }
Weather & Clock Dashboard — free Firefox new tab extension with full keyboard navigation. Pressing / focuses search, Esc clears focus. MIT licensed.
Top comments (0)