All hooks / Events and input

useHotkey

586 B minified and brotliedSourceMarkdown✓ Works in all modern browsers

Calls handler when a keyboard shortcut is pressed, e.g. 'Escape', 'mod+k', 'shift+/'.

mod is Cmd on Apple devices and Ctrl elsewhere. Modifiers must match exactly, so 'k' does not fire for Ctrl+K. Ignored during IME composition, and while typing in inputs, textareas, selects, and contenteditable, except Escape. Key names follow KeyboardEvent.key, case-insensitive; esc and space work as aliases.

Import

import { useHotkey } from '@vincent.ri/react-tils'
// or only this hook
import { useHotkey } from '@vincent.ri/react-tils/useHotkey'

Usage

useHotkey('mod+k', () => setPaletteOpen(true))
useHotkey('Escape', () => setPaletteOpen(false), { enabled: paletteOpen })

Live demo

Press ⌘K / Ctrl+K, then Escape. Or press g, then i.

palette closedg i pressed: 0

When to use it

Global shortcuts like a command palette (mod+k), closing a modal with Escape, or / to focus search.

When not to

The shortcut belongs to one focused element; use its onKeyDown prop. For text input handling, use the input's own events.

API

function useHotkey(hotkey: string, handler: (event: KeyboardEvent) => void, options?: HotkeyOptions): void
ParameterDescription
hotkeyModifiers and a key joined by +: ctrl, alt, shift, meta, mod. Separate steps with spaces for a sequence: 'g i' fires after g then i, each within a second of the previous one.
handlerCalled with the KeyboardEvent. Can change every render.
optionsenabled, preventDefault, enableInInputs. All optional.

Types

export type HotkeyOptions = {
  /** Listen only while `true`. Default `true`. */
  enabled?: boolean;
  /** Call `event.preventDefault()` on a match, e.g. to stop the browser's own `ctrl+k`. Default `true`. */
  preventDefault?: boolean;
  /** Also fire while typing in inputs, textareas, selects, and contenteditable. Default `false` (Escape always fires). */
  enableInInputs?: boolean;
};

Browser support

Uses only long-established browser features, so it works wherever React does.

First version with support, from MDN's compatibility data (web-features 3.42.0, @mdn/browser-compat-data 8.1.5).

Coming from another library?

Other libraries call this useKey, useKeyPress, useHotkeys.