Skip to main content

Function Signature

function useHotkeys<T extends HTMLElement>(
  keys: Keys,
  callback: HotkeyCallback,
  options?: OptionsOrDependencyArray,
  dependencies?: OptionsOrDependencyArray
): RefObject<T>
The useHotkeys hook is the primary API for binding keyboard shortcuts to React components. It returns a ref that can be attached to any HTML element to scope the hotkey to that element.

Parameters

keys
Keys
required
The keyboard shortcut(s) to listen for. Can be a single string or an array of strings.Type definition:
type Keys = string | readonly string[]
Examples:
  • "ctrl+s" - Single combination
  • "ctrl+k, cmd+k" - Multiple combinations (comma-separated)
  • ["ctrl+k", "cmd+k"] - Multiple combinations (array)
  • "a>b>c" - Key sequence
callback
HotkeyCallback
required
Function called when the hotkey is triggered.Type definition:
type HotkeyCallback = (
  keyboardEvent: KeyboardEvent,
  hotkeysEvent: HotkeysEvent
) => void
Parameters:
  • keyboardEvent - The native browser KeyboardEvent
  • hotkeysEvent - Enhanced event object containing hotkey metadata
options
Options | DependencyList
Configuration options for the hotkey behavior, or a dependency array for React.See the Options section below for all available configuration options.
dependencies
DependencyList
React dependency array. When provided, the callback is memoized with these dependencies.If options is a dependency array, this parameter should contain the Options object.

Returns

ref
RefObject<T>
A React ref object that can be attached to an HTML element to scope the hotkey to that element.Type:
RefObject<T extends HTMLElement>
When the ref is not attached to any element (remains null), the hotkey listens globally on the document.

Options

The Options object accepts the following properties:
enabled
boolean | Trigger
default:"true"
Determines if the hotkey is enabled. Can be a boolean or a function that returns a boolean.Type:
type Trigger = boolean | ((keyboardEvent: KeyboardEvent, hotkeysEvent: HotkeysEvent) => boolean)
enableOnFormTags
readonly FormTags[] | boolean
default:"false"
Enable hotkeys on form elements like inputs, textareas, and selects.Type:
type FormTags = 'input' | 'textarea' | 'select' | 'INPUT' | 'TEXTAREA' | 'SELECT' 
  | 'searchbox' | 'slider' | 'spinbutton' | 'menuitem' | 'menuitemcheckbox' 
  | 'menuitemradio' | 'option' | 'radio' | 'textbox'
Pass true to enable on all form tags, or pass an array of specific tags.
enableOnContentEditable
boolean
default:"false"
Enable hotkeys on elements with contentEditable attribute.
preventDefault
boolean | Trigger
default:"false"
Prevent the default browser behavior for the keyboard event.
keydown
boolean
default:"true"
Trigger the callback on keydown event.
keyup
boolean
default:"false"
Trigger the callback on keyup event.
scopes
string | readonly string[]
Scope(s) for the hotkey. Only active when the scope is enabled via HotkeysProvider.Type:
type Scopes = string | readonly string[]
splitKey
string
default:"+"
Character used to split keys in combination shortcuts (e.g., ctrl+s).
delimiter
string
default:","
Character used to separate different hotkey combinations.
ignoreModifiers
boolean
default:"false"
Ignore modifier keys (ctrl, alt, shift, meta) when matching hotkeys.
ignoreEventWhen
(e: KeyboardEvent) => boolean
Custom function to conditionally ignore keyboard events.
description
string
Human-readable description of what the hotkey does. Useful for documentation or help menus.
useKey
boolean
default:"false"
Listen to the produced key (event.key) instead of the key code (event.code).
Use this option when you want to listen to the character being typed rather than the physical key position.
sequenceSplitKey
string
default:">"
Character used to split key sequences (e.g., a>b>c).
sequenceTimeoutMs
number
default:"1000"
Timeout in milliseconds to wait for the next key in a sequence.
document
Document
Custom document object to attach event listeners to. Useful for iframes or shadow DOM.
eventListenerOptions
EventListenerOptions
Options passed to the native addEventListener method.Type:
type EventListenerOptions = {
  capture?: boolean
  once?: boolean
  passive?: boolean
  signal?: AbortSignal
} | boolean
metadata
Record<string, unknown>
Custom metadata to store with the hotkey. Accessible in the callback via hotkeysEvent.metadata.

Usage Examples

Basic Usage

import { useHotkeys } from 'react-hotkeys-hook'

function App() {
  useHotkeys('ctrl+s', () => {
    console.log('Save triggered!')
  })

  return <div>Press Ctrl+S to save</div>
}

Multiple Key Combinations

useHotkeys('ctrl+k, cmd+k', (event) => {
  event.preventDefault()
  openCommandPalette()
})

With Options

useHotkeys(
  'ctrl+s',
  () => saveDocument(),
  {
    preventDefault: true,
    enableOnFormTags: ['input', 'textarea'],
    description: 'Save the current document'
  }
)

Scoped to an Element

function SearchBox() {
  const ref = useHotkeys<HTMLDivElement>('/', () => {
    // This only triggers when the div (or its children) is focused
    focusSearchInput()
  })

  return (
    <div ref={ref} tabIndex={-1}>
      <input type="text" placeholder="Search..." />
    </div>
  )
}

Key Sequences

useHotkeys('g>i', () => {
  // Triggered by pressing 'g' then 'i' within 1 second
  navigateToInbox()
}, {
  sequenceTimeoutMs: 1000
})

With Dependencies

function Editor({ documentId }) {
  const saveDocument = useCallback(() => {
    api.save(documentId)
  }, [documentId])

  // Callback updates when documentId changes
  useHotkeys('ctrl+s', saveDocument, [documentId])

  return <div>Editor content...</div>
}

Conditional Enabling

const [isEditing, setIsEditing] = useState(false)

useHotkeys('ctrl+s', () => saveDocument(), {
  enabled: isEditing // Only active when editing
})

Using the Hotkeys Event

useHotkeys('ctrl+k, cmd+k', (keyboardEvent, hotkeysEvent) => {
  console.log('Pressed keys:', hotkeysEvent.keys)
  console.log('Modifiers:', {
    ctrl: hotkeysEvent.ctrl,
    alt: hotkeysEvent.alt,
    shift: hotkeysEvent.shift,
    meta: hotkeysEvent.meta
  })
  console.log('Description:', hotkeysEvent.description)
  console.log('Custom metadata:', hotkeysEvent.metadata)
}, {
  description: 'Open command palette',
  metadata: { category: 'navigation' }
})

Important Notes

When a ref is attached to an element, the hotkey will only trigger when that element (or its children) is focused. Make sure the element is focusable by setting tabIndex={-1} if needed.
By default, hotkeys are disabled on form elements. Use enableOnFormTags to enable them on inputs, textareas, and selects.
Hotkeys containing both the splitKey (default: +) and sequenceSplitKey (default: >) are not supported and will trigger a console warning.

See Also

Build docs developers (and LLMs) love