Altcademy - a Forbes magazine logo Best Coding Bootcamp 2023

What is Turbolinks in Ruby on Rails?

Turbolinks is a gem that comes bundled with Ruby on Rails applications by default. It was introduced in Rails 4 and has since gone through a few iterations, with the latest version being Turbolinks 5. The purpose of Turbolinks is to speed up page loading in web applications by making navigation faster.

In this post, we'll be discussing what Turbolinks is, how it works, and how to use it effectively in your Ruby on Rails applications. We'll start by explaining the problem that Turbolinks solves, then dive into the mechanics behind it, and finally look at some code examples to demonstrate how you can implement Turbolinks in your Rails apps.

When a user navigates from one page to another in a traditional web application, the browser has to perform several time-consuming tasks. First, it has to send a request to the server, which then processes the request and sends back the HTML for the new page. Once the browser receives the HTML, it has to parse it, execute any JavaScript, and apply any CSS styles before rendering the new page.

All of these steps can add up, resulting in slow page loads and a poor user experience. This is where Turbolinks comes in. Turbolinks aims to speed up page navigation by changing the way browsers load and display new pages.

Turbolinks works by intercepting link clicks and form submissions, making an AJAX (Asynchronous JavaScript and XML) request to the server for the new page's HTML, and then swapping out the <body> and <title> elements of the current page with those from the new page. This entire process happens without the browser having to fully reload the page, which results in faster navigation and a smoother user experience.

Here's a step-by-step breakdown of how Turbolinks does this:

  1. When a user clicks on a link or submits a form, Turbolinks intercepts the event and prevents the browser from making a full page reload.
  2. Turbolinks then makes an AJAX request to the server for the new page's HTML.
  3. Once the server responds with the new HTML, Turbolinks extracts the <body> and <title> elements from the new page.
  4. Turbolinks swaps out the current page's <body> and <title> elements with those from the new page.
  5. Finally, Turbolinks updates the browser's URL and history to reflect the new page.

This entire process is much faster than a full page reload because the browser doesn't need to re-parse and re-execute all the JavaScript and CSS on the page. Instead, Turbolinks just updates the parts of the page that actually changed, which is usually just the <body> and <title> elements.

As mentioned earlier, Turbolinks comes bundled with Rails by default. This means that you don't have to do anything special to start using it in your application. However, there are a few things you should be aware of to ensure that your application works smoothly with Turbolinks.

In some cases, you might want to perform a specific action when navigating to a certain page, such as scrolling to the top of the page. To do this, you can use the data-turbolinks-action attribute on your links. For example:

<a href="/some-page" data-turbolinks-action="scroll_to_top">Go to some page</a>

When a user clicks on this link, Turbolinks will navigate to the specified page and then scroll to the top of the page. You can also use this attribute on form elements:

<form action="/submit" method="post" data-turbolinks-action="scroll_to_top">
  <!-- Your form fields go here -->
  <input type="submit" value="Submit">
</form>

Handling JavaScript events

When using Turbolinks, it's important to be aware of the JavaScript events that it triggers. Since Turbolinks doesn't perform a full page reload, some events that you might be used to (such as $(document).ready() in jQuery) won't be triggered on every page navigation.

Instead, you should listen for Turbolinks-specific events. Here's a list of the main events that Turbolinks triggers:

  • turbolinks:click: Triggered when a link is clicked, before Turbolinks makes the AJAX request.
  • turbolinks:request-start: Triggered when the AJAX request is about to be made.
  • turbolinks:request-end: Triggered when the AJAX request completes.
  • turbolinks:before-cache: Triggered before Turbolinks stores the current page in its cache.
  • turbolinks:render: Triggered after Turbolinks has replaced the <body> and <title> elements.
  • turbolinks:load: Triggered after Turbolinks has finished updating the page.

Here's an example of how you might use these events in your application:

document.addEventListener('turbolinks:load', function () {
  // Initialize your JavaScript libraries or components here
  console.log('Turbolinks finished loading the page');
});

Some JavaScript libraries or components might not work well with Turbolinks out of the box. This is because they might rely on events or behavior that only occur during a full page reload.

In these cases, you have a few options:

  1. Modify the library or component to work with Turbolinks. This might involve changing event listeners or modifying initialization code.
  2. Disable Turbolinks for specific links or forms by adding the data-turbolinks="false" attribute. For example:
<a href="/some-page" data-turbolinks="false">Go to some page without Turbolinks</a>
  1. Disable Turbolinks entirely for your application. To do this, remove the turbolinks gem from your Gemfile, and remove the //= require turbolinks line from your app/assets/javascripts/application.js file.

Conclusion

Turbolinks is a powerful tool that can help you speed up page navigation in your Ruby on Rails applications. By understanding how it works and how to use it effectively, you can provide a smoother and more enjoyable user experience for your users.

Remember to be mindful of Turbolinks-specific events, and to test your JavaScript code with Turbolinks enabled to ensure compatibility. And if you run into issues with third-party libraries or components, consider modifying them to work with Turbolinks or disabling Turbolinks for specific parts of your application.

Happy coding!