Skip to main content
The Options type defines the configuration object you can pass to customize the behavior of the useHotkeys hook.

Type Definition

type Options = {
  enabled?: Trigger
  enableOnFormTags?: readonly FormTags[] | boolean
  enableOnContentEditable?: boolean
  ignoreEventWhen?: (e: KeyboardEvent) => boolean
  splitKey?: string
  delimiter?: string
  scopes?: Scopes
  keyup?: boolean
  keydown?: boolean
  preventDefault?: Trigger
  description?: string
  document?: Document
  ignoreModifiers?: boolean
  eventListenerOptions?: EventListenerOptions
  useKey?: boolean
  sequenceTimeoutMs?: number
  sequenceSplitKey?: string
  metadata?: Record<string, unknown>
}

Parameters

enabled
Trigger
default:"true"
Main setting that determines if the hotkey is enabled or not. Can be a boolean or a function that returns a boolean based on the keyboard and hotkeys event.
// Simple boolean
useHotkeys('ctrl+k', handleSearch, { enabled: true })

// Function based on event
useHotkeys('ctrl+k', handleSearch, {
  enabled: (keyboardEvent, hotkeysEvent) => {
    return keyboardEvent.shiftKey === false
  }
})
enableOnFormTags
readonly FormTags[] | boolean
default:"false"
Enable hotkeys on a list of form element tags. Can be a boolean to enable on all form tags, or an array of specific tags.
// Enable on all form tags
useHotkeys('ctrl+s', handleSave, { enableOnFormTags: true })

// Enable on specific tags only
useHotkeys('ctrl+s', handleSave, {
  enableOnFormTags: ['input', 'textarea']
})
enableOnContentEditable
boolean
default:"false"
Enable hotkeys on elements with the contentEditable attribute set to true.
useHotkeys('ctrl+b', handleBold, {
  enableOnContentEditable: true
})
ignoreEventWhen
(e: KeyboardEvent) => boolean
default:"undefined"
A function to conditionally ignore events. Return true to ignore the event.
useHotkeys('enter', handleSubmit, {
  ignoreEventWhen: (e) => e.target.value.length === 0
})
splitKey
string
default:"+"
Character used to split keys in hotkey combinations.
// Use default + separator
useHotkeys('ctrl+k', handleSearch)

// Use custom separator
useHotkeys('ctrl-k', handleSearch, { splitKey: '-' })
delimiter
string
default:","
Character used to separate different hotkeys when defining multiple hotkeys in a single string.
// Use default , delimiter
useHotkeys('ctrl+k, cmd+k', handleSearch)

// Use custom delimiter
useHotkeys('ctrl+k | cmd+k', handleSearch, { delimiter: '|' })
scopes
Scopes
default:"undefined"
Scope(s) in which the hotkey is active. Can be a single scope string or an array of scopes.
// Single scope
useHotkeys('ctrl+k', handleSearch, { scopes: 'search' })

// Multiple scopes
useHotkeys('esc', handleClose, { scopes: ['modal', 'dialog'] })
keyup
boolean
default:"undefined"
Trigger the callback on the keyup event instead of keydown.
useHotkeys('space', handleToggle, { keyup: true })
keydown
boolean
default:"true"
Trigger the callback on the keydown event. This is the default behavior.
useHotkeys('ctrl+s', handleSave, { keydown: true })
preventDefault
Trigger
default:"false"
Prevent the default browser behavior for the hotkey. Can be a boolean or a function.
// Always prevent default
useHotkeys('ctrl+s', handleSave, { preventDefault: true })

// Conditionally prevent default
useHotkeys('ctrl+k', handleSearch, {
  preventDefault: (keyboardEvent, hotkeysEvent) => {
    return hotkeysEvent.alt === false
  }
})
description
string
default:"undefined"
A description of what the hotkey does. Useful for generating help menus or documentation.
useHotkeys('ctrl+k', handleSearch, {
  description: 'Open search dialog'
})
document
Document
default:"undefined"
Listen to events on a specific document instead of the default window.
const iframeDoc = iframeRef.current?.contentDocument

useHotkeys('ctrl+k', handleSearch, {
  document: iframeDoc
})
ignoreModifiers
boolean
default:"false"
Ignore modifier keys (ctrl, alt, shift, meta) when matching hotkeys.
// Will match 'k' with or without modifiers
useHotkeys('k', handleKey, { ignoreModifiers: true })
eventListenerOptions
EventListenerOptions
default:"undefined"
Pass through options to the underlying addEventListener call.
useHotkeys('ctrl+k', handleSearch, {
  eventListenerOptions: {
    capture: true,
    passive: false
  }
})
useKey
boolean
default:"false"
Listen to the produced key instead of the code. This is useful for non-US keyboards.
useHotkeys('z', handleUndo, { useKey: true })
sequenceTimeoutMs
number
default:"1000"
The timeout in milliseconds to wait for the next key to be pressed in a sequence.
useHotkeys('g>i', handleGoToInbox, {
  sequenceTimeoutMs: 2000
})
sequenceSplitKey
string
default:">"
The character used to split the sequence of keys.
// Use default > separator
useHotkeys('g>i', handleGoToInbox)

// Use custom separator
useHotkeys('g->i', handleGoToInbox, { sequenceSplitKey: '->' })
metadata
Record<string, unknown>
default:"undefined"
Custom metadata to store and retrieve with the hotkey. Useful for storing additional context.
useHotkeys('ctrl+k', handleSearch, {
  metadata: {
    category: 'navigation',
    priority: 'high'
  }
})

Usage Examples

Basic Configuration

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

function SearchDialog() {
  const [isOpen, setIsOpen] = useState(false)

  useHotkeys('ctrl+k', () => setIsOpen(true), {
    preventDefault: true,
    description: 'Open search dialog'
  })

  return <Dialog open={isOpen} />
}

Advanced Configuration

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

function Editor() {
  const [content, setContent] = useState('')
  const isDirty = useRef(false)

  useHotkeys('ctrl+s', handleSave, {
    enabled: isDirty.current,
    preventDefault: true,
    enableOnFormTags: ['textarea'],
    description: 'Save document',
    metadata: {
      category: 'file',
      action: 'save'
    }
  })

  return <textarea value={content} onChange={(e) => {
    setContent(e.target.value)
    isDirty.current = true
  }} />
}

Scoped Hotkeys

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

function App() {
  return (
    <HotkeysProvider initiallyActiveScopes={['app']}>
      <MainContent />
      <Modal />
    </HotkeysProvider>
  )
}

function Modal() {
  useHotkeys('esc', handleClose, {
    scopes: 'modal',
    description: 'Close modal'
  })

  return <div>Modal content</div>
}

Sequence Hotkeys

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

function Gmail() {
  useHotkeys('g>i', () => navigate('/inbox'), {
    description: 'Go to inbox',
    sequenceTimeoutMs: 1500
  })

  useHotkeys('g>s', () => navigate('/starred'), {
    description: 'Go to starred',
    sequenceTimeoutMs: 1500
  })

  return <div>Gmail interface</div>
}

Build docs developers (and LLMs) love