### Start Development Server for Library
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/AGENTS.md
Starts the development server specifically for the library package.
```bash
npm run -w packages/react-hotkeys-hook dev
```
--------------------------------
### Install Dependencies
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/packages/documentation/README.md
Run this command to install all project dependencies.
```bash
$ yarn
```
--------------------------------
### Start Local Development Server
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/packages/documentation/README.md
Starts a local development server with live reloading enabled.
```bash
$ yarn start
```
--------------------------------
### Install via Bun
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/packages/documentation/docs/documentation/installation.mdx
Use this command to add react-hotkeys-hook to your project using Bun.
```shell
bun i react-hotkeys-hook
```
--------------------------------
### Install ts-key-enum
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/packages/documentation/docs/documentation/advanced-usage.mdx
Install the ts-key-enum library to get type-safe key names for your hotkeys.
```bash
npm install ts-key-enum
```
--------------------------------
### Start Function
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/packages/documentation/docs/api/use-record-hotkeys.mdx
The 'start' function, used to begin recording keystrokes.
```typescript
start: () => void
```
--------------------------------
### Install via NPM
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/packages/documentation/docs/documentation/installation.mdx
Use this command to add react-hotkeys-hook to your project using NPM.
```shell
npm i react-hotkeys-hook
```
--------------------------------
### Install via Yarn
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/packages/documentation/docs/documentation/installation.mdx
Use this command to add react-hotkeys-hook to your project using Yarn.
```shell
yarn add react-hotkeys-hook
```
--------------------------------
### Global Hotkeys Example
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/packages/documentation/docs/documentation/useHotkeys/scoping-hotkeys.mdx
Demonstrates how two separate components listening for the same hotkey ('c') will both trigger when the key is pressed, as hotkeys are global by default.
```jsx
function UnscopedHotkey() {
const [count, setCount] = useState(0)
useHotkeys('c', () => setCount(prevCount => prevCount + 1))
return (
)
```
--------------------------------
### Example Usage of useRecordHotkeys with Blacklist
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/packages/documentation/docs/api/use-record-hotkeys.mdx
An example of using useRecordHotkeys with a specified blacklist to ignore 'tab' and 'enter' keys.
```javascript
const [keys, { start, stop }] = useRecordHotkeys(false, ['tab', 'enter']);
```
--------------------------------
### Basic useRecordHotkeys Example
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/packages/documentation/docs/documentation/use-record-hotkeys.mdx
Demonstrates the basic usage of useRecordHotkeys to record and display pressed keys. It returns a Set of keys and controls to manage the recording process.
```jsx
function ExampleComponent() {
const [keys, { start, stop, isRecording }] = useRecordHotkeys()
return (
Is recording: {isRecording ? 'yes' : 'no'}
Recorded keys: {Array.from(keys).join(' + ')}
)
}
```
--------------------------------
### Developer Warning Example
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/AGENTS.md
Shows how to use `console.warn` for developer-facing warnings that should appear in production code.
```javascript
console.warn
```
--------------------------------
### Basic Hotkey Combination
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/packages/documentation/docs/documentation/useHotkeys/basic-usage.mdx
This example demonstrates how to use `useHotkeys` to listen for multiple key combinations. It increments a counter each time one of the specified hotkeys is pressed. Ensure you have `useState` imported from React.
```jsx
function ExampleComponent() {
const [count, setCount] = useState(0)
useHotkeys(
'ctrl+shift+a+c, c, shift+c, alt+n, ctrl+d, meta+d',
() => setCount(prevCount => prevCount + 1)
)
return (
Received the combination {count} times.
)
}
```
--------------------------------
### Listen to Physical Key '!' (Shift+1)
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/packages/documentation/docs/documentation/useHotkeys/ignore-layouts.mdx
This example demonstrates the default behavior of listening to the physical key combination 'shift+1' to trigger a hotkey. It's layout-independent.
```jsx
function ExampleComponent() {
const [count, setCount] = useState(0)
useHotkeys('shift+1', () => setCount(prevCount => prevCount + 1))
return (
Pressed the '!' key {count} times.
)
}
```
--------------------------------
### Main Hook Export Example
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/AGENTS.md
Illustrates the pattern of exporting the main hook as the default export from the library's entry point.
```typescript
export default function useHotkeys()
```
--------------------------------
### Define Hotkeys with Descriptions and Metadata
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/packages/documentation/docs/documentation/advanced-usage.mdx
Register hotkeys with descriptions and custom metadata to build dynamic help panels. This example shows how to structure hotkey data and render it.
```tsx
function useActiveHotkeys() {
// You would collect this from your components or a registry
const hotkeys = [
{ keys: 'ctrl+s', description: 'Save document', scope: 'editor' },
{ keys: 'ctrl+z', description: 'Undo', scope: 'editor' },
{ keys: 'esc', description: 'Close modal', scope: 'modal' },
];
return hotkeys;
}
function HelpPanel() {
const hotkeys = useActiveHotkeys();
return (
Keyboard Shortcuts
{hotkeys.map(h => (
{h.keys} — {h.description}
))}
);
}
```
```tsx
useHotkeys('ctrl+s', handleSave, {
description: 'Save the current document',
metadata: { category: 'file' },
});
```
--------------------------------
### Basic Hotkey Usage
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/README.md
Register a hotkey ('ctrl+k') to increment a counter. This example demonstrates the fundamental use of the `useHotkeys` hook.
```jsx
import { useHotkeys } from 'react-hotkeys-hook'
export const ExampleComponent = () => {
const [count, setCount] = useState(0)
useHotkeys('ctrl+k', () => setCount(prevCount => prevCount + 1))
return (
Pressed {count} times.
)
}
```
--------------------------------
### Optional Chaining Example
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/AGENTS.md
Demonstrates the use of optional chaining (`?.`) to safely access nested properties that might be null or undefined.
```javascript
e.target?.isContentEditable
```
--------------------------------
### Listen to Produced Character '?'
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/packages/documentation/docs/documentation/useHotkeys/ignore-layouts.mdx
This example uses `useKey: true` to listen for the produced character '?'. This is useful when the character itself is important, regardless of the physical keys pressed.
```jsx
function ExampleComponent() {
const [count, setCount] = useState(0)
useHotkeys('?', () => setCount(prevCount => prevCount + 1), { useKey: true })
return (
Pressed '?' {count} times.
)
}
```
--------------------------------
### Stale State Example
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/packages/documentation/docs/documentation/useHotkeys/setting-callback-dependencies.mdx
This example demonstrates the stale state problem where a hotkey callback references a state variable directly, leading to outdated values being used after the first update.
```jsx
function ExampleComponent() {
const [count, setCount] = useState(0)
const ref = useHotkeys('b', () => setCount(count + 1))
return (
Pressed the 'b' key {count} times.
)
}
```
--------------------------------
### Listen to Produced Character '!'
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/packages/documentation/docs/documentation/useHotkeys/ignore-layouts.mdx
This example uses the `useKey: true` option to listen for the produced character '!' regardless of the physical keys pressed. This approach is layout-dependent.
```jsx
function ExampleComponent() {
const [count, setCount] = useState(0)
useHotkeys('!', () => setCount(prevCount => prevCount + 1), { useKey: true })
return (
Pressed the '!' key {count} times.
)
}
```
--------------------------------
### TODO Comment Example
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/AGENTS.md
Example of a TODO comment used to mark future improvements or areas for refactoring.
```javascript
// TODO: Make modifiers work with sequences
```
--------------------------------
### Listen to '+' Character with Custom Split Key
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/packages/documentation/docs/documentation/useHotkeys/ignore-layouts.mdx
This example demonstrates how to listen for the '+' character when it's used as a hotkey by changing the `splitKey` option to '-' to avoid conflicts with the default '+' split key.
```js
// Listen to the '+' character by changing the splitKey
useHotkeys('ctrl-+', addItem, { splitKey: '-' })
```
--------------------------------
### Listen to Physical Key ';'
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/packages/documentation/docs/documentation/useHotkeys/ignore-layouts.mdx
This example shows how to listen to the physical key code 'Semicolon' to trigger a hotkey, ensuring layout independence. The code name is case-insensitive.
```jsx
function ExampleComponent() {
const [count, setCount] = useState(0)
useHotkeys('Semicolon', () => setCount(prevCount => prevCount + 1))
return (
Pressed the ';' key {count} times.
)
}
```
--------------------------------
### Type-Only Import Example
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/AGENTS.md
Demonstrates the use of `import type` for importing types only, which does not affect the JavaScript output.
```typescript
import type { Hotkey } from './types'
```
--------------------------------
### Basic Usage of useHotkeys Hook
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/packages/documentation/docs/intro.mdx
Use the useHotkeys hook to bind a keyboard shortcut ('a') to a callback function that increments a counter. This example demonstrates a simple counter that updates when the 'a' key is pressed.
```jsx
function MyComponent() {
const [count, setCount] = useState(0);
useHotkeys('a', () => setCount(count => count + 1));
return (
Pressed the 'a' key {count} times.
);
}
```
--------------------------------
### Biome Ignore Comment Example
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/AGENTS.md
Demonstrates how to use a `biome-ignore` comment to bypass specific linting rules for a line of code.
```javascript
// biome-ignore lint/correctness/useExhaustiveDependencies
```
--------------------------------
### Type Guard Example
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/AGENTS.md
Illustrates the use of a type guard function to narrow down the type of a variable within a conditional block.
```typescript
isReadonlyArray(enabledOnTags)
```
--------------------------------
### Create Custom Hooks for Editor Shortcuts
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/packages/documentation/docs/documentation/advanced-usage.mdx
Encapsulate related hotkeys within a custom hook to maintain clean components and enforce consistent behavior. This example defines editor-specific shortcuts.
```tsx
function useEditorShortcuts() {
const { enableScope, disableScope } = useHotkeysContext();
useHotkeys('ctrl+s', saveDocument, {
scopes: 'editor',
preventDefault: true,
description: 'Save document',
});
useHotkeys('ctrl+z', undo, {
scopes: 'editor',
preventDefault: true,
description: 'Undo',
});
useHotkeys('ctrl+shift+z', redo, {
scopes: 'editor',
preventDefault: true,
description: 'Redo',
});
return { enableScope, disableScope };
}
function Editor() {
useEditorShortcuts();
return
{/* editor content */}
;
}
```
--------------------------------
### Generic Ref Example
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/AGENTS.md
Shows how to use TypeScript generics with `useRef` to provide type safety for DOM elements or mutable values.
```typescript
useRef(null)
```
--------------------------------
### Custom Key Splitter for Key Combinations
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/packages/documentation/docs/api/use-hotkeys.mdx
Change the default '+' character used to join keys in a combination if you need to listen for the '+' key itself. This example uses '-' as the splitter.
```javascript
useHotkeys('ctrl-+', zoomIn, { splitKey: '-' })
```
--------------------------------
### Bind Hotkeys to a Specific Document in an Iframe
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/packages/documentation/docs/api/use-hotkeys.mdx
This example demonstrates binding hotkey event listeners to a specific Document object obtained from within an iframe, useful for isolated contexts.
```javascript
import FrameComponent from 'react-frame-component'
const InsideFrameComponent = () => {
const { document } = useFrame()
useHotkeys("s", () => console.log("Triggered inside iframe"), { document })
return
....
}
```
--------------------------------
### Control Scopes Programmatically
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/packages/documentation/docs/documentation/hotkeys-provider.mdx
Use the `useHotkeysContext` hook to get functions for enabling, disabling, and toggling scopes. This allows for dynamic control over which hotkey groups are active.
```jsx
import { useHotkeysContext } from 'react-hotkeys-hook';
function MyComponent() {
const { enableScope, disableScope, toggleScope } = useHotkeysContext();
return (
)
}
```
--------------------------------
### Pass Custom Event Listener Options
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/packages/documentation/docs/documentation/advanced-usage.mdx
Provide custom options to the underlying `addEventListener` call for fine-grained control over event propagation and behavior. This example sets `passive` and `capture` options.
```tsx
useHotkeys('ctrl+s', handleSave, {
eventListenerOptions: { passive: true, capture: true },
});
```
--------------------------------
### Build Documentation Site
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/AGENTS.md
Builds the documentation site for the project.
```bash
npm run build:documentation
```
--------------------------------
### useHotkeys Function Signature Overloads
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/packages/documentation/docs/api/use-hotkeys.mdx
Demonstrates how to pass a dependency array when no options are needed.
```APIDOC
## Function signature overloads
If you want to pass a dependency array but do not need any options, you can pass the array as the third argument instead of the fourth:
```ts
function useHotkeys(
keys: string,
callback: (event: KeyboardEvent, handler: HotkeysEvent) => void,
deps: any[] = []
): React.RefCallback
```
So instead of:
```js
useHotkeys('a', () => someDependency, undefined, [someDependency]);
```
You can write:
```js
useHotkeys('a', () => someDependency, [someDependency]);
```
```
--------------------------------
### Readonly Array Example
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/AGENTS.md
Illustrates the use of the `readonly` modifier for arrays that should not be modified after initialization.
```typescript
readonly FormTags[]
```
--------------------------------
### Listen to Physical Key Combinations
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/packages/documentation/docs/documentation/useHotkeys/ignore-layouts.mdx
Demonstrates listening to physical key combinations like 'ctrl+Equal', 'ctrl+Minus', and 'mod+Slash'. These are layout-independent.
```js
useHotkeys('ctrl+Equal', zoomIn, { preventDefault: true })
useHotkeys('ctrl+Minus', zoomOut, { preventDefault: true })
useHotkeys('mod+Slash', toggleComment)
```
--------------------------------
### useKey Parameter Explanation
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/packages/documentation/docs/api/use-record-hotkeys.mdx
Demonstrates the behavior of the 'useKey' parameter, which determines whether to record physical keys or produced characters.
```typescript
useKey: boolean // default: false
```
--------------------------------
### Use Hotkeys with Dependency Array
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/README.md
Demonstrates using the `useHotkeys` hook with a dependency array as the third parameter when no special options are needed.
```javascript
useHotkeys('ctrl+k', () => console.log(counter + 1), [counter])
```
--------------------------------
### Build Main Library Package
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/AGENTS.md
Builds the main library package located in packages/react-hotkeys-hook.
```bash
npm run build
```
--------------------------------
### useHotkeys Hook with Dependencies
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/packages/react-hotkeys-hook/README.md
Demonstrates the use of the useHotkeys hook with a dependency list. The callback is memoized, so external variables used within it should be included in the dependency array to ensure updates.
```javascript
import { useHotkeys } from 'react-hotkeys-hook';
function MyComponent() {
const [count, setCount] = React.useState(0);
useHotkeys('ctrl+s', () => {
console.log('The count is: ', count);
}, [count]);
return (
);
}
```
--------------------------------
### Build Static Content
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/packages/documentation/README.md
Generates static files in the build directory for production hosting.
```bash
$ yarn build
```
--------------------------------
### Listen to Produced Characters for Symbols
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/packages/documentation/docs/documentation/useHotkeys/ignore-layouts.mdx
Shows how to listen for produced characters like '+', '=', and '/' using `useKey: true`. This approach is layout-dependent.
```js
useHotkeys('+', addItem, { useKey: true })
useHotkeys('=', resetZoom, { useKey: true })
useHotkeys('/', focusSearch, { useKey: true })
```
--------------------------------
### Deploy to GitHub Pages
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/packages/documentation/README.md
Commands to deploy the site to the gh-pages branch, with options for SSH or HTTPS authentication.
```bash
$ USE_SSH=true yarn deploy
```
```bash
$ GIT_USER= yarn deploy
```
--------------------------------
### Scoping Hotkeys to an Element
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/packages/documentation/docs/api/use-hotkeys.mdx
Attach the ref callback returned by `useHotkeys` to an element to make the hotkey only active when that element or its children have focus. This example demonstrates scoping hotkeys to a specific button.
```jsx
function App() {
const [count, setCount] = useState(0);
const ref = useHotkeys("s", () => setCount((prevCount) => prevCount + 1));
return (
Count: {count}
);
}
```
--------------------------------
### Simplified useHotkeys Signature with Dependency Array
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/packages/documentation/docs/api/use-hotkeys.mdx
When only a dependency array is needed and no options, it can be passed as the third argument instead of the fourth. This simplifies the signature for common cases.
```ts
function useHotkeys(
keys: string,
callback: (event: KeyboardEvent, handler: HotkeysEvent) => void,
deps: any[] = []
): React.RefCallback
// Instead of:
// useHotkeys('a', () => someDependency, undefined, [someDependency]);
// You can write:
// useHotkeys('a', () => someDependency, [someDependency]);
```
--------------------------------
### Listen to All Keys
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/packages/documentation/docs/api/use-hotkeys.mdx
Use the '*' wildcard to listen for any key press. The handler provides information about the pressed key.
```jsx
useHotkeys('*', (_, handler) => alert(handler.key))
```
--------------------------------
### useHotkeys Options
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/packages/documentation/docs/api/use-hotkeys.mdx
Configuration options for the useHotkeys hook.
```APIDOC
## `enabled`
### Description
Determines if the callback should be triggered. Pass `false` to disable the hotkey entirely, or a function that receives the keyboard event and returns `true` or `false`.
When `enabled` is a boolean `false`, the event listeners are removed from the DOM. When `enabled` is a function that returns `false`, the listeners stay attached but the callback is skipped.
### Type
`Trigger` (boolean | (e: KeyboardEvent) => boolean)
### Default
`true`
## `enableOnFormTags`
### Description
By default, hotkeys are disabled while the user is focused on a form element. Set this to `true` to enable hotkeys on all form tags, or pass an array of specific tags.
### Type
`FormTags[] | boolean`
### Default
`false`
### Example
```js
useHotkeys('ctrl+s', save, { enableOnFormTags: ['input', 'textarea', 'select'] })
```
## `enableOnContentEditable`
### Description
Enable hotkeys on elements with the `contentEditable` attribute.
### Type
`boolean`
### Default
`false`
## `ignoreEventWhen`
### Description
Fine-grained control over which events to ignore. Return `true` from the function to skip handling the event.
### Type
`(e: KeyboardEvent) => boolean`
### Example
```js
useHotkeys('a', someCallback, {
ignoreEventWhen: (e) => {
return e.target.className.includes('special-element')
},
})
```
## `splitKey`
### Description
The character that joins keys within a single combination. The default is `+`, so `shift+a` triggers when the user presses Shift **and** A together.
Change this if you need to listen for the `+` key itself.
### Type
`string`
### Default
`"+"`
### Example
```js
useHotkeys('ctrl-+', zoomIn, { splitKey: '-' })
```
## `delimiter`
### Description
The character that separates different hotkey combinations mapped to the same callback. The default is `,`, so `ctrl+a, shift+b` listens for either combination.
### Type
`string`
### Default
`","`
## `sequenceSplitKey`
### Description
The character that separates keys in a sequential hotkey. The default is `>`, so `g>h>i` requires pressing G, then H, then I in sequence.
### Type
`string`
### Default
`">"`
## `scopes`
### Description
Assign the hotkey to one or more scopes. Scopes let you group hotkeys and enable or disable them together via `HotkeysProvider`. See the [Grouping Hotkeys](/docs/documentation/hotkeys-provider) documentation for details.
### Type
`string | string[]`
### Default
`"*"`
## `keyup`
### Description
Trigger the callback on the browser's `keyup` event.
### Type
`boolean`
### Default
`false`
## `keydown`
### Description
Trigger the callback on the browser's `keydown` event. This is the default.
### Type
`boolean`
### Default
`true`
### Tip
Listening to both `keydown` and `keyup`
If you set `keyup: true` without explicitly setting `keydown`, the hook assumes you only want `keyup`. To listen to both, set both options:
```js
useHotkeys('a', callback, {
keydown: true,
keyup: true
})
```
## `preventDefault`
### Description
Prevent the browser's default behavior for the matched keystroke. Useful for overriding shortcuts like `meta+s` (save page).
### Type
`Trigger` (boolean | (e: KeyboardEvent) => boolean)
### Default
`false`
### Example
```js
useHotkeys('meta+s', someCallback, {
preventDefault: true,
});
```
## `description`
### Description
A human-readable description of what the hotkey does. Useful for building help panels or shortcut reference lists.
### Type
`string`
### Default
`undefined`
## `document`
### Description
Bind the event listeners to a specific `Document` object instead of the global `document`. Useful for apps running inside iframes.
### Type
`Document`
### Default
`undefined`
### Example
```js
import FrameComponent from 'react-frame-component'
const InsideFrameComponent = () => {
const { document } = useFrame()
useHotkeys("s", () => console.log("Triggered inside iframe"), { document })
return
....
}
```
```
--------------------------------
### Run Biome Linter with Auto-fix
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/AGENTS.md
Runs the Biome linter across all packages and automatically fixes linting issues.
```bash
npm run lint
```
--------------------------------
### Build Library Package Only
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/AGENTS.md
Builds only the library package using TypeScript and Vite.
```bash
npm run -w packages/react-hotkeys-hook build
```
--------------------------------
### Making Non-focusable Elements Focusable for Hotkeys
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/packages/documentation/docs/api/use-hotkeys.mdx
For non-focusable elements like `div` or `span`, add the `tabIndex={0}` prop to allow them to receive focus and thus trigger scoped hotkeys. This example shows how to make divs focusable.
```jsx
function App() {
const [count, setCount] = useState(0);
const ref = useHotkeys("s", () => setCount((prevCount) => prevCount + 1));
return (
Count: {count}
Focusing this area won't trigger the hotkey.
Focusing this area will trigger the hotkey.
);
}
```
--------------------------------
### Run All Tests
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/AGENTS.md
Executes all tests in the project, which are run using Vitest in the packages/react-hotkeys-hook package.
```bash
npm run test
```
--------------------------------
### Check for Pressed Modifier Keys in Callbacks
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/packages/documentation/docs/documentation/is-hotkey-pressed.mdx
Use isHotkeyPressed within event callbacks to conditionally alter behavior based on modifier key states. For example, modify a click handler's action if the 'shift' key is held.
```jsx
function ExampleComponent() {
const [count, setCount] = useState(0);
const onClick = () => isHotkeyPressed('shift')
? setCount(count => count - 1)
: setCount(count => count + 1);
return (
The count is: {count}
Hold Shift while clicking to decrease.
)
}
```
--------------------------------
### Custom Metadata for Hotkeys
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/packages/documentation/docs/documentation/typescript.mdx
Demonstrates attaching custom metadata, such as a description and category, to hotkeys for use cases like building a help panel.
```typescript
useHotkeys('ctrl+s', handleSave, {
description: 'Save the current document',
metadata: { category: 'file', showInHelp: true },
});
```
--------------------------------
### Run Biome Formatter
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/AGENTS.md
Runs the Biome formatter across all packages to ensure consistent code style.
```bash
npm run format
```
--------------------------------
### Import Hook via CDN
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/packages/documentation/docs/documentation/installation.mdx
Import the ES Module directly from unpkg.com for use in your project.
```js
import { useHotkeys } from 'https://unpkg.com/react-hotkeys-hook@latest/dist/react-hotkeys-hook.esm.js';
```
--------------------------------
### Listen to Produced Character (v5 with useKey)
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/packages/documentation/docs/migrate-to-5.mdx
To replicate v4's behavior of listening to the produced character (layout-dependent), set the `useKey` option to `true` in v5.
```javascript
useHotkeys('!', callback, { useKey: true })
```
--------------------------------
### Format Packages with Write Directly
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/AGENTS.md
Formats the packages directory and writes changes directly to the files.
```bash
npx @biomejs/biome format --write packages
```
--------------------------------
### useHotkeys Options
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/packages/documentation/docs/api/use-hotkeys.mdx
Configuration options for the useHotkeys hook to customize its behavior.
```APIDOC
## `ignoreModifiers`
```ts
ignoreModifiers: boolean // default: false
```
Ignore modifier keys (`shift`, `alt`, `ctrl`, `meta`) when matching hotkeys. Useful when you want to listen for a character regardless of how it is typed — for example, listening for `/` to focus a search field, whether the user presses the dedicated `/` key or `shift+7` on some layouts.
## `useKey`
```ts
useKey: boolean // default: false
```
Listen to the produced character instead of the physical key code. Useful when you want to match a specific symbol (like `!` or `?`) regardless of which physical keys produce it on the user's layout.
## `sequenceTimeoutMs`
```ts
sequenceTimeoutMs: number // default: 1000
```
The time window in milliseconds for sequential hotkeys. If the user does not press the next key within this window, the sequence resets.
## `eventListenerOptions`
```ts
eventListenerOptions: EventListenerOptions // default: undefined
```
Pass custom options to the underlying `addEventListener` call, such as `{ passive: true }` or `{ capture: true }`.
## `metadata`
```ts
metadata: Record // default: undefined
```
Attach arbitrary custom data to the hotkey. You can retrieve it from the `handler` object in the callback (`handler.metadata`). Useful for building dynamic shortcut registries or help panels.
## `deps`
```ts
deps: any[] // default: []
```
Dependency array for the callback, just like React's `useCallback` or `useMemo`. If your callback references unstable or changing values, add them here so the callback stays up to date.
```
--------------------------------
### Typed Options for Hotkey Configuration
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/packages/documentation/docs/documentation/typescript.mdx
Illustrates the fully typed `options` object, providing autocomplete and type checking for configuration properties like `enabled`, `preventDefault`, `scopes`, and `enableOnFormTags`.
```typescript
useHotkeys('ctrl+s', handleSave, {
enabled: true,
preventDefault: true,
scopes: ['editor'],
enableOnFormTags: ['input', 'textarea'],
});
```
--------------------------------
### useRecordHotkeys with Blacklist
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/packages/documentation/docs/documentation/use-record-hotkeys.mdx
Shows how to use useRecordHotkeys while ignoring specific keys like 'tab' and 'enter' by passing a blacklist array. Blacklisted keys retain their default behavior.
```jsx
function ExampleWithBlacklist() {
const [keys, { start, stop, resetKeys, isRecording }] = useRecordHotkeys(false, ['tab', 'enter']);
return (
Recording (ignoring Tab and Enter): {isRecording ? 'yes' : 'no'}
Recorded keys: {Array.from(keys).join(' + ')}
);
}
```
--------------------------------
### Listen to Physical Keystroke (v5 Default)
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/packages/documentation/docs/migrate-to-5.mdx
In v5, useHotkeys listens to physical key codes by default. Use this when you want layout-independent hotkey detection.
```javascript
useHotkeys('shift+1', callback)
```
--------------------------------
### Set Initially Active Scopes
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/packages/documentation/docs/documentation/hotkeys-provider.mdx
Initialize the `HotkeysProvider` with specific scopes already active by passing an array of scope names to the `initiallyActiveScopes` prop. Remember to include '*' if you want the wildcard scope to be active by default.
```jsx
import { HotkeysProvider } from 'react-hotkeys-hook';
function App() {
return (
My App
)
}
```
--------------------------------
### Bind Key Combinations
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/packages/documentation/docs/documentation/useHotkeys/basic-usage.mdx
Listen for key combinations, such as 'Shift+C', to trigger a callback. This is useful for shortcuts like creating new items.
```jsx
function CreateIssue() {
const [showIssueCreatorModal, setShowIssueCreatorModal] = useState(false)
useHotkeys('shift+c', () => setShowIssueCreatorModal(true))
return (
<>
{showIssueCreatorModal &&
MODAL CONTENT
}
{!showIssueCreatorModal &&
issue list
}
>
)
}
```
--------------------------------
### Run Tests Once (No Watch Mode)
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/AGENTS.md
Runs tests in the library package once without entering watch mode.
```bash
npm run -w packages/react-hotkeys-hook vitest run
```
--------------------------------
### Migrate useHotkeys Options: combinationKey and splitKey
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/packages/documentation/docs/migrate-to-5.mdx
In v5, `combinationKey` is renamed to `splitKey` and `splitKey` is renamed to `delimiter`. This snippet shows the v4 to v5 option mapping.
```javascript
// v4
useHotkeys('ctrl+a, shift+b', callback, { combinationKey: '-', splitKey: ';' })
// v5
useHotkeys('ctrl+a, shift+b', callback, { splitKey: '-', delimiter: ';' })
```
--------------------------------
### Listen to Both Keydown and Keyup Events
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/packages/documentation/docs/api/use-hotkeys.mdx
To trigger callbacks on both 'keydown' and 'keyup' events, explicitly set both options to true. If only 'keyup' is true, 'keydown' is implicitly false.
```javascript
useHotkeys('a', callback, {
keydown: true,
keyup: true
})
```
--------------------------------
### Combine 'enabled' and 'preventDefault'
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/packages/documentation/docs/documentation/useHotkeys/disable-hotkeys.mdx
Demonstrates combining the 'enabled' option (set to always return false) with 'preventDefault: true'. This ensures the hotkey is disabled and default browser behavior is prevented.
```jsx
function ExampleComponent() {
useHotkeys('meta+s', () => alert('We saved your progress!'), {
enabled: () => false,
preventDefault: true,
})
return (
Press cmd+s (or ctrl+s on non-Mac) to open the custom save dialog.
)
}
```
--------------------------------
### Blacklist Parameter Explanation
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/packages/documentation/docs/api/use-record-hotkeys.mdx
Details the 'blacklist' parameter, an array of key names to ignore during recording.
```typescript
blacklist: string[] // default: []
```
--------------------------------
### useHotkeys(keys, callback)
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/README.md
The useHotkeys hook allows you to easily bind keyboard shortcuts to functions within your React components. It takes a keys argument, which can be a single key or an array of keys, and a callback function that will be executed when the keys are pressed. The dependencies array ensures that the callback is memoized correctly, similar to React's useCallback hook.
```APIDOC
## useHotkeys(keys, callback)
### Description
This hook binds keyboard shortcuts to a callback function. The `keys` argument specifies which key combination triggers the callback, and the `callback` function contains the logic to be executed. A `dependencies` array is used for memoization, ensuring the callback updates when referenced variables change.
### Parameters
#### Path Parameters
None
#### Query Parameters
None
#### Request Body
None
### Parameters
- **keys**: (string | string[]) - Required - The key or array of keys to listen for.
- **callback**: (function) - Required - The function to execute when the keys are pressed.
- **dependencies**: (DependencyList) - Optional - An array of dependencies for the callback, similar to `useCallback`.
### Request Example
```javascript
useHotkeys('ctrl+s', () => {
console.log('Saved!');
}, [someVariable]);
```
### Response
This hook does not return a value directly. Its effect is to bind the hotkey.
#### Success Response (200)
N/A
#### Response Example
N/A
```
--------------------------------
### Typing the Ref for Scoped Hotkeys
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/packages/documentation/docs/documentation/typescript.mdx
Shows how to type the returned ref using `useHotkeys` for full type safety when scoping hotkeys to a specific element.
```tsx
import { useHotkeys } from "react-hotkeys-hook";
import { useState } from "react";
interface Props {
hotKey: string;
}
const MyComponent = ({ hotKey }: Props) => {
const [count, setCount] = useState(0);
const ref = useHotkeys(
hotKey,
() => setCount(prevCount => prevCount + 1)
);
return (
The count is {count}.
)
}
```
--------------------------------
### Use Function Keys
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/packages/documentation/docs/api/use-hotkeys.mdx
Bind actions to function keys like F1, F5, etc.
```jsx
useHotkeys('f5', () => alert('F5 was pressed'))
```
--------------------------------
### Run Tests Matching Name
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/AGENTS.md
Executes tests whose names match the specified string.
```bash
npx vitest run -t "should listen to key presses"
```
--------------------------------
### Importing useRecordHotkeys
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/packages/documentation/docs/documentation/use-record-hotkeys.mdx
Import the useRecordHotkeys hook from the 'react-hotkeys-hook' package.
```javascript
import { useRecordHotkeys } from 'react-hotkeys-hook';
```
--------------------------------
### Run Single Test Matching Pattern
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/AGENTS.md
Executes a single test whose name matches the provided pattern.
```bash
npx vitest run --testNamePattern "test name"
```
--------------------------------
### useRecordHotkeys
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/packages/documentation/docs/api/use-record-hotkeys.mdx
Records keystrokes and provides controls to manage the recording process. It returns a Set of recorded keys and an object with methods to control recording.
```APIDOC
## `useRecordHotkeys`
### Description
Records keystrokes and provides controls to manage the recording process. It returns a Set of recorded keys and an object with methods to control recording.
### Signature
```ts
function useRecordHotkeys(useKey?: boolean, blacklist?: string[]): [Set, {
start: () => void,
stop: () => void,
resetKeys: () => void,
isRecording: boolean
}]
```
### Parameters
#### `useKey`
- **Type**: `boolean`
- **Default**: `false`
- **Description**: If `true`, records the produced character instead of the physical key code. For example, `useKey: false` records "shift+1" for Shift+1, while `useKey: true` records "!" for Shift+1 on a US layout.
#### `blacklist`
- **Type**: `string[]`
- **Default**: `[]`
- **Description**: An array of key names to ignore while recording. Blacklisted keys retain their default behavior and are not added to the recorded set.
### Return Value
Returns a tuple containing:
1. **`keys`** (`Set`): A `Set` of the keys that have been recorded. Each key appears only once. Use `Array.from(keys)` to convert it to an array.
2. **`controls`** (`object`): An object with the following methods and properties:
* **`start`** (`() => void`): Begins recording keystrokes.
* **`stop`** (`() => void`): Stops recording keystrokes.
* **`resetKeys`** (`() => void`): Clears the recorded keys.
* **`isRecording`** (`boolean`): `true` while recording is active, `false` otherwise.
### Example
```js
const [keys, { start, stop, resetKeys, isRecording }] = useRecordHotkeys(false, ['tab', 'enter']);
```
```
--------------------------------
### Hotkey Scopes with HotkeysProvider
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/README.md
Use scopes to group hotkeys and manage their activation. The `HotkeysProvider` must wrap the application or relevant part of it.
```jsx
const App = () => {
return (
)
}
export const ExampleComponent = () => {
const [count, setCount] = useState(0)
useHotkeys('ctrl+k', () => setCount(prevCount => prevCount + 1), { scopes: ['settings'] })
return (
Pressed {count} times.
)
}
```
--------------------------------
### useHotkeys(keys, callback)
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/README.md
The useHotkeys hook allows you to easily define keyboard shortcuts within your React components. It accepts a keys configuration, a callback function to execute when the keys are pressed, and optional configuration options.
```APIDOC
## useHotkeys(keys, callback)
### Description
This hook registers keyboard shortcuts within a React component. It listens for specified key combinations and executes a provided callback function when those combinations are detected.
### Method
`useHotkeys` (Hook)
### Parameters
#### Path Parameters
None
#### Query Parameters
None
#### Request Body
None
### Parameters
#### `keys`
- **Type**: `string` or `string[]`
- **Required**: Yes
- **Description**: Defines the hotkeys to listen for. Can be a single key, multiple keys separated by commas, or an array of key strings. Modifier combinations are supported.
#### `callback`
- **Type**: `(event: KeyboardEvent, handler: HotkeysEvent) => void`
- **Required**: Yes
- **Description**: The function to be executed when the specified hotkeys are pressed. It receives the native `KeyboardEvent` and a `HotkeysEvent` object.
#### `options`
- **Type**: `Options`
- **Required**: No
- **Default value**: `{}`
- **Description**: An object to customize the hook's behavior. Refer to the library's documentation for available options.
#### `deps`
- **Type**: `DependencyList`
- **Required**: No
- **Default value**: `[]`
- **Description**: An array of dependencies, similar to React's `useEffect` hook, to control when the hotkey listener should re-register.
### Request Example
```javascript
useHotkeys('ctrl+s, meta+s', (event, handler) => {
// Handle save action
console.log('Save shortcut pressed!');
}, [saveAction]);
```
### Response
This hook does not return a value directly, but triggers the callback function when hotkeys are pressed.
```
--------------------------------
### Using Dependency Array with useHotkeys
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/packages/documentation/docs/documentation/useHotkeys/setting-callback-dependencies.mdx
Provide a dependency array to useHotkeys to ensure the callback uses the latest values of external references like memoized values, props, or state. This prevents stale state issues when the callback relies on values that change over time.
```jsx
function ExampleComponent() {
const [count, setCount] = useState(0)
const squaredCount = useMemo(() => count * 2, [count])
const ref = useHotkeys('b', () => setCount(squaredCount + 1), [squaredCount])
return (
Pressed the 'b' key {squaredCount} times.
)
}
```
--------------------------------
### Run Specific Test File
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/AGENTS.md
Executes all tests contained within a specific test file.
```bash
npx vitest run src/test/useHotkeys.test.tsx
```
--------------------------------
### Multiple Key Combinations
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/packages/documentation/docs/api/use-hotkeys.mdx
Define a single callback for multiple independent key combinations.
```jsx
useHotkeys('w, a, s, d', () => alert('Player moved!'))
```
--------------------------------
### Differentiate Hotkeys with Object Values
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/packages/documentation/docs/api/use-hotkeys.mdx
Use an object to define hotkeys and their corresponding actions. The `hotkey` property in the handler identifies the matched shortcut.
```jsx
const HOTKEYS = {
ACTION_A: 'ctrl+a',
ACTION_B: 'shift+b',
}
useHotkeys(Object.values(HOTKEYS), (_, { hotkey }) => {
switch (hotkey) {
case HOTKEYS.ACTION_A: alert('You pressed ctrl+a!');
break;
case HOTKEYS.ACTION_B: alert('You pressed shift+b!');
break;
}
})
```
--------------------------------
### Run Tests in Library Package
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/AGENTS.md
Executes tests specifically within the library package.
```bash
npm run -w packages/react-hotkeys-hook test
```
--------------------------------
### Sequential Hotkeys
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/packages/documentation/docs/documentation/useHotkeys/basic-usage.mdx
Listen for keys pressed in sequence using the '>' character. The callback is triggered only after the entire sequence is completed.
```jsx
function ExampleComponent() {
const [count, setCount] = useState(0)
useHotkeys('g>h>i', () => setCount(prevCount => prevCount + 1))
return (
Received the combination {count} times.
)
}
```
--------------------------------
### Recording Produced Characters with useRecordHotkeys
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/packages/documentation/docs/documentation/use-record-hotkeys.mdx
Configures useRecordHotkeys to record the produced characters (e.g., '!') instead of key codes (e.g., 'shift+1') by passing true as the first argument.
```jsx
const [keys, controls] = useRecordHotkeys(true); // records characters like "!" instead of "shift+1"
```
--------------------------------
### Import isHotkeyPressed
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/packages/documentation/docs/documentation/is-hotkey-pressed.mdx
Import the isHotkeyPressed function from the 'react-hotkeys-hook' package before use.
```javascript
import { isHotkeyPressed } from 'react-hotkeys-hook';
```
--------------------------------
### Type-Safe Key Names with TypeScript
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/packages/documentation/docs/documentation/typescript.mdx
Demonstrates how TypeScript catches incorrect types for the `keys` argument at compile time. Ensure the `hotKey` prop is a string or array of strings.
```tsx
import { useHotkeys } from "react-hotkeys-hook";
import { useState } from "react";
interface Props {
hotKey: number; // ❌ wrong type
}
const MyComponent = ({ hotKey }: Props) => {
const [count, setCount] = useState(0);
// TypeScript error: hotKey must be a string
useHotkeys(hotKey, () => setCount(prevCount => prevCount + 1));
return (
The count is {count}.
)
}
```
--------------------------------
### Migrate HotkeysProvider Context: enabledScopes to activeScopes
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/packages/documentation/docs/migrate-to-5.mdx
The `enabledScopes` property from `useHotkeysContext` has been renamed to `activeScopes` in v5 to avoid confusion.
```javascript
// v4
const { enabledScopes } = useHotkeysContext()
// v5
const { activeScopes } = useHotkeysContext()
```
--------------------------------
### Bind Multiple Keys to One Callback
Source: https://github.com/johannesklauss/react-hotkeys-hook/blob/main/packages/documentation/docs/documentation/useHotkeys/basic-usage.mdx
Bind several different key combinations to the same callback function by separating them with a comma or by passing an array.
```jsx
function ExampleComponent() {
const [count, setCount] = useState(0)
useHotkeys('ctrl+shift+a+c, c, shift+c', () => setCount(prevCount => prevCount + 1))
return (
Received the combination {count} times.
)
}
```