DEV Community

Cover image for How to add hotkeys to your Rails app with Stimulus
Rails Designer
Rails Designer

Posted on • Originally published at railsdesigner.com

How to add hotkeys to your Rails app with Stimulus

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

Hotkey navigation refers to the implementation of keyboard shortcuts that allow users to quickly navigate through and interact with a web application'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>
Enter fullscreen mode Exit fullscreen mode
import {install} from '@github/hotkey'

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

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);
  }
}
Enter fullscreen mode Exit fullscreen mode

And then the HTML:

<a href="/" data-controller="hotkey" data-hotkey="g h">Home</a>
Enter fullscreen mode Exit fullscreen mode

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 UI Components Library for Rails.

More than just link redirects

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>
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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).

Top comments (0)