How to add Hotkeys to your Rails App with Stimulus

An abstract representation of buttons (keys) on a screen

When your app is growing, more screens will be added. It is at this point, you might want to consider adding another way for your (power) users to navigate through your app. Introducing: keyboard shortcuts (or hotkeys)!

Hotkey navigation refers to the implementation of keyboard shortcuts that allow users to quickly navigate through and interact with a (web) app’s interface without relying on mouse clicks.

Luckily there are a ton of libraries out there that make it easy to add this to a Rails app. The one I’ve been using for all my Rails apps, is hotkey from GitHub. It’s an easy-to-use, lightweight, dependency-free library, that, who-would-have-thought, works great with Stimulus. Bingo!

How GitHub’s hotkey library works

The library works great as a vanilla solution. Let’s look at the code coming from the README. First there’s the HTML:

<a href="/" data-hotkey="g h">Home</a>
import {install} from '@github/hotkey'

// Install all the hotkeys on the page
for (const el of document.querySelectorAll('[data-hotkey]')) {
  install(el)
}

You need to initialize the JavaScript, but every element with the data-hotkey attribute is then turned into a “hotkey”. Pretty hot!

This snippet will redirect to the root folder (/) after pressing first g and then h. The library also allows to combine keys, like Shift+?.

Using a Stimulus controller

While above code is really clean, I prefer to use Stimulus. It’s a great way to make the code a bit more explicit and remove some indirectness.

How would such a Stimulus controller look like? Just a few lines of code really! When going through below steps, make sure you have the hotkey library available. Either through node (esbuild or bun) or importmaps. The example below uses the node version.

import { Controller } from "@hotwired/stimulus";
import { install, uninstall } from "@github/hotkey";

export default class extends Controller {
  connect() {
    install(this.element);
  }
}

And then the HTML:

<a href="/" data-controller="hotkey" data-hotkey="g h">Home</a>

Notice that this HTML is a tiny bit more verbose than the previous HTML. It needs the data-controller="hotkey" attribute. I would argue this is actually better, as it follows the Stimulus conventions and any code related to hotkeys is sure to be found in the file app/javacripts/controllers/hotkey_controller.js.

Looking for Global Hotkeys component done for you (and other UI Components), check out Rails Designer, the first professionally-designed UI Components Library for Rails.

If you use modals in your Rails app you are in luck! You can open these using the same controller too. Just be sure to add the correct turbo-frame attributes, like so:

<a href="/help/" data-controller="hotkey" data-hotkey="Shift+?" data-turbo-frame="modal">Help dialog</a>

It’s that simple: just add data-turbo-frame="modal" attribute like you would with any normal link in Rails.

How about submitting a form using the common CMD+Enter? This can be done as well, but needs a bit more work. That is because, by default, the hotkey library won’t fire off the event within form inputs. As that could become annoying quickly.

All you need is to add a hotkey-scope. Like so:

  <form>
    <textarea name="message" id="message_content"></textarea>

    <button type="submit" data-controller="hotkey" data-hotkey="Meta+Enter" hotkey-scope="message_content">Submit</button>
  </form>

Notice the value of hotkey-scope matches the id of the textarea (message_content). When the user presses Meta+Enter the form gets submitted. Bam!

And that one small (copy-pasteable) Stimulus controller is all that is needed to get keyboard shortcuts in your Rails app. Other things to explore next are: how to disconnect (uninstall the event listeners/unregister the hotkey) and a way to, optional, disable keyboard shortcuts per user for accessibility reasons (see this section in the readme).

Get UI & Product Engineering Insights for Rails Apps (and product updates!)

Published at . Last updated at . Have suggestions or improvements on this content? Do reach out.

UI components for Ruby on Rails apps

$ 129 one-time
payment

Get Access
  • One-time Payment

  • Access to the Entire Library

  • Built using ViewComponent

  • Designed with Tailwind CSS

  • Enhanced with Hotwire