Migrating to v5
Version 5.0.0 brings significant improvements to react-hotkeys-hook, including support for scopes, key sequences, and a major refactor of the hook internals. This guide will help you migrate from v4 to v5.
Breaking Changes
v5 introduces breaking changes that require code updates. Please review the sections below carefully.
ESM-Only Package
v5 is now ESM-only. You must ensure your toolchain supports ES modules.
The package no longer ships with CommonJS builds. If your project uses CommonJS, you’ll need to:
- Update your build configuration to support ESM
- Use a bundler that supports ES modules (Webpack 5+, Vite, Rollup, etc.)
- Ensure your
package.json has "type": "module" or uses .mjs extensions
Callback Signature Changes
The callback signature has changed. Your callback now receives (keyboardEvent, hotkeysEvent) consistently.
Before (v4):
useHotkeys('ctrl+k', (event) => {
console.log(event); // KeyboardEvent
});
After (v5):
useHotkeys('ctrl+k', (keyboardEvent, hotkeysEvent) => {
console.log(keyboardEvent); // KeyboardEvent
console.log(hotkeysEvent); // HotkeysEvent with additional metadata
});
The hotkeysEvent parameter includes useful information:
interface HotkeysEvent {
key: string;
method: string;
scope?: string;
hotkey?: string; // Which combination triggered the handler
}
Update your type definitions:
import type { HotkeysEvent } from 'react-hotkeys-hook';
// Before
const handler = (event: KeyboardEvent) => {
// ...
};
// After
const handler = (event: KeyboardEvent, hotkeysEvent: HotkeysEvent) => {
// ...
};
Migration Steps
Update Package
Install the latest version of react-hotkeys-hook:npm install react-hotkeys-hook@latest
# or
yarn add react-hotkeys-hook@latest
# or
pnpm add react-hotkeys-hook@latest
Ensure ESM Support
Verify your build toolchain supports ES modules. Update your bundler configuration if necessary.
Update Callback Signatures
Update all your hotkey callbacks to accept two parameters:// Update this pattern throughout your codebase
useHotkeys('ctrl+k', (event) => {
// Before: single parameter
});
// To this
useHotkeys('ctrl+k', (keyboardEvent, hotkeysEvent) => {
// After: two parameters
});
Update Type Definitions
If you use TypeScript and have explicit type annotations, update them:import type { HotkeysEvent } from 'react-hotkeys-hook';
type HotkeyCallback = (
event: KeyboardEvent,
hotkeysEvent: HotkeysEvent
) => void;
Test Your Application
Run your tests and manually test all hotkey functionality to ensure everything works as expected.
New Features in v5
Global Scopes (v5.2.0)
Control hotkeys across your app with global scopes:
import { HotkeysProvider, useHotkeys, useHotkeysContext } from 'react-hotkeys-hook';
function App() {
return (
<HotkeysProvider initiallyActiveScopes={['main']}>
<YourApp />
</HotkeysProvider>
);
}
function Component() {
const { enableScope, disableScope, toggleScope } = useHotkeysContext();
useHotkeys('ctrl+k', () => console.log('Main scope'), {
scopes: ['main']
});
useHotkeys('ctrl+p', () => console.log('Modal scope'), {
scopes: ['modal']
});
const openModal = () => {
enableScope('modal');
disableScope('main');
};
return <button onClick={openModal}>Open Modal</button>;
}
Key Sequences (v5.2.0)
Trigger actions with key sequences like Vim:
useHotkeys('g>g', () => {
console.log('Go to top');
});
// Custom sequence separator
useHotkeys('ctrl+k,ctrl+s', () => {
console.log('Save all');
}, { sequenceSplitKey: ',' });
// Configure timeout
useHotkeys('d>d', () => {
console.log('Delete line');
}, { sequenceTimeoutMs: 1000 }); // 1 second timeout
Enhanced Options (v5.2.0)
New options for more control:
useHotkeys('ctrl+k', handler, {
// Use only specific key types
useKey: true,
// Custom delimiter for key combinations
delimiter: '+',
// Custom split key for sequences
splitKey: '>',
// Listen on keyup instead of keydown
keyup: true,
keydown: false,
// Add description for documentation
description: 'Open command palette',
// Use document instead of window
document: document,
// Ignore modifier keys
ignoreModifiers: true,
// Event listener options
eventListenerOptions: { capture: true },
// Enable on contentEditable elements
enableOnContentEditable: true,
// Conditionally ignore events
ignoreEventWhen: (event) => event.target.classList.contains('ignore')
});
ARIA Roles Support (v5.2.0)
enableOnFormTags now accepts ARIA roles:
useHotkeys('enter', handler, {
enableOnFormTags: ['INPUT', 'TEXTAREA', 'searchbox', 'textbox']
});
Works with shadow DOM and custom elements via composedPath().
Improved Key Mapping (v5.2.0)
Better handling of modifier keys:
mod key works consistently across platforms (Cmd on Mac, Ctrl on Windows/Linux)
meta, OS keys properly mapped
- Improved code→key normalization
- Consistent
HotkeysEvent passed to callbacks
BoundHotkeysProxyProvider (v5.1.0)
Advanced provider for performance-critical scenarios:
import { BoundHotkeysProxyProvider } from 'react-hotkeys-hook';
function App() {
return (
<BoundHotkeysProxyProvider>
<YourApp />
</BoundHotkeysProxyProvider>
);
}
Better Developer Experience (v5.1.0)
- Helper warnings when missing provider for scopes
- Improved error messages
- Fixed edge cases with modifier-only hotkeys
- Better OS/meta key handling
Common Issues
Missing HotkeysProvider
If you use scopes, you must wrap your app with HotkeysProvider:
import { HotkeysProvider } from 'react-hotkeys-hook';
function App() {
return (
<HotkeysProvider>
<YourApp />
</HotkeysProvider>
);
}
ESM Import Errors
If you encounter import errors:
- Ensure your
package.json supports ESM
- Update your bundler configuration
- Check that all dependencies support ESM
Type Errors
If you get TypeScript errors after upgrading:
- Update your callback signatures to accept two parameters
- Import
HotkeysEvent type from the package
- Clear your TypeScript cache:
rm -rf node_modules/.cache
Getting Help
If you encounter issues during migration: