Rails Progress Indicator for Turbolinks Using Nprogress
Contrary to popular opinion, I’m a fan of Turbolinks. I leave it enabled in all my Rails applications. Most of the negative opinions I hear relate to it “breaking” third-party jQuery plugins. I say “breaking” because it’s not really changing the plugin’s behavior – just requires the plugin to be initialized differently.
With Turbolinks enabled, interacting with an application feels smooth and fast. No more full page refreshes.
Every once in awhile we’ll stumble on a page request takes longer than others. Rather than having the user sit there thinking nothing is happening, we can offer better feedback through a loading progress bar, specifically nprogress. I’ve found it to be the perfect companion to Turbolinks to create a great user experience.
In a traditional web application, when we click a link or submit a form, we get a loading spinner where the favicon typically appears. We might also see text in the status bar saying “Connecting…” or “Loading…”. These are the loading indications that internet users have become accustomed to.
By adopting Turbolinks, we not longer get those loading feedback mechanisms because the request for the new page is asynchronous. Once the request is complete, the new content is rendered in place of the previous page’s body element. For fast page loads, this isn’t a problem. However, if you have applications like mine, every once in awhile, you might have a page request take a few seconds (reasons for this are beyond the scope of this article). In those cases, a user might click a link and sit there for 2-3 sec. without any indication the page is loading. While Turbolinks generally improves the user experience of our application, having no user feedback for several seconds is not ideal (ideally, you’d want to address a page request that takes multiple seconds). This is where
nprogress can help.
nprogress is a progress loading indicator, like what you see on YouTube.
We’ll first add
nprogress-rails to our Gemfile:
Bundle to install the new gem:
We first include the
Note: If you’re familiar with Turbolinks and its events, you’ll recognize the events triggered.
By default, the
nprogress loading bar is anchored to the top of the browser window, but we need to include some CSS to make this work. Let’s open the
app/assets/stylesheets/application.scss manifest file and add the following:
nprogress-bootstrap isn’t necessary if you don’t use Bootstrap in your application. I typically do, so I’m going to include it.
At this point, we’ll have a working loading indicator. But what if we want to tweak the styles to match your application’s theme?
Customizing Nprogress Styles
nprgress styles are Sass, we can overwrite the variables for customization.
There are 3 variables available to overwite:
For Bark, we have an aqua accent color with use throughout the site. It made sense for the
nprogress loading indicator to be that same color.
Back in our
app/assets/stylesheets/application.scss, I overwrote the variable before including the
nprogress source code:
nprogress to be a great companion library to Turbolinks. The two libraries together provide a much better user experience over full page refreshes. Turbolinks helps asynchronously load the page content that’s changing and
nprogress gives the user feedback that their request is in progress. Now, even when a user has to suffer through multi-second page loads, at least they’ll know it’s not broken and don’t have to click again.
The latest version of Turbolinks has a progress bar built-in. I’m looking forward to removing the dependency if it performs similarly.