Skip to main content
Version: 4.0

Disable/Enable Hotkeys

We are now able to register our hotkeys, scope them to the component (or part of a component) and prevent stale state inside our callback. But our hotkeys are always active. If the component has received focus, it will always trigger. However, sometimes we want to dynamically decide if the hotkey should even be enabled.

There are multiple ways to disable a hotkey. Let's go through all of them.

Dynamically disable or enable

Toggle hotkeys with the enabled flag

Using the enabled flag in the options object, we can dynamically tell useHotkeys if the hotkey should be active or not.

Live Editor
Result
Loading...

This is useful to programmatically decide (depending on some internal state of our app or user input) if the hotkey should be active or not. enabled takes a Trigger type, so it can either be a boolean or a function that returns a boolean. See the documentation for the enabled option for more information.

Tip

If we use the returned ref of the callback to scope our hotkey to a specific sub-tree of our component, note that this will automatically activate or deactivate our hotkey depending on which part of the page has active focus.


Prevent default browser behavior

Some hotkeys like meta + s are already assigned to a browser function, in this case saving a website to the users local disk. Sometimes we want to override these hotkeys to implement our own functionality. Maybe we want to build a text editor or some other user based creation tool that needs a save shortcut to save the current progress. It would be silly to introduce a new shortcut for saving the users progress, since every user knows that meta + s is the universal shortcut for saving.

To prevent the default browser behavior, we can just set preventDefault to true in our options:

Live Editor
Result
Loading...
Warning

Please be aware that there are some hotkeys that we cannot override, because they would interfere with a safe browsing experience for the user. These depend on the browser. For example in Chrome, most notably those are meta + w which closes a tab, meta + n for opening a new window and meta + t to open a new tab. Additionally meta + shift + w (closing all tabs of the current window), meta + shift + n (opening incognito window) and meta + shift + t (reopen the last closed tab) cannot be overridden. meta + up + 1..9 on the other hand focuses the corresponding tab of the active window and also cannot be overridden.


Disable callback execution

In the first section we set enabled to false to disable our hotkey. Internally this will also unbind our event listeners from the DOM. To keep the event listeners but not execute the callback, we can give enabled a function that returns false.

Live Editor
Result
Loading...

We can combine both the enabled and preventDefault options.

function ExampleComponent() {
useHotkeys('meta+s', () => alert('We saved your progress!'), {
enabled: () => false,
preventDefault: true,
})

return (
<div>
<p>Press cmd+s (or ctrl+s for non mac) to open custom save dialog.</p>
</div>
)
}

This might be preferred if we want to build a custom hook on top of useHotkeys that always prevents the default behavior.

Notice the different behavior for the enabled option

If enabled is set to false the internal browser event will not trigger at all, therefore no browser behavior will happen. If we set enabled to () => false our callback still won't get executed, but the event will trigger and therefore potential browser behavior will happen.


Enable hotkeys on form fields

By default, hotkeys won't trigger when the user is focusing a form field. This is the expected case most of the time. For example, if we'd listen for the hotkey 'p' on a review page for apps and a user would try to type This app is simply the best into the review input field, the resulting text would be This a is simly the best. Same with keystrokes that start with shift + ... since this normally capitalizes a letter. So it is good, that useHotkeys is smart enough to back off during focused form fields. However, sometimes you still want hotkeys to be enabled even when the user is focusing on an input field. There might be again the need so save the users progress. Our previous example would not trigger if the user is focusing a form field. Instead, we have to enable the hotkey on certain form fields. We can use the enableOnFormTags option for that which takes an array of form tags:

function ExampleComponent() {
useHotkeys('meta+s', (e) => {
e.preventDefault()

alert('We saved your progress!')
// ... set up our own saving dialog.
}, {
enableOnFormTags: ['input', 'select', 'textarea']
})

return (
<div>
<p>Press cmd+s (or ctrl+s for non mac) to open custom save dialog.</p>
</div>
)
}

We tell useHotkeys that the given keystrokes should be listened to and the callback executed even when the user is currently focusing an input, select or textarea field. To enable the hotkey on any input tag, set the enableOnFormTags option to true.


Enable hotkeys on tags leveraging contentEditable

The contentEditable attribute allows users to edit text even though it is not part of an input field. For example a <div> tag could have the contentEditable attribute. Sometimes we want hotkeys to still trigger, even though a user is focusing an editing a tags content. A good example for this might be the editor on medium.com. useHotkeys provides an option for that:

Live Editor
Result
Loading...