Skip to main content

11 How To Use Turbolinks clearCache()

Episode 161 · December 5, 2016

Improve your Turbolinks implementation by using the clearCache method to reload pages

Turbolinks Javascript Frontend


# create.js.erb
Turbolinks.clearCache()

Transcripts

How to use Turbolinks clearCache()

In this episode, I want to talk about the Turbolinks clearCache() method and how you can use it to your advantage in your Rails applications. We'll first look at an example and discuss how this method can fix some inconsistencies resulting from Turbolinks.

We see that this episode here is marked incomplete. Clicking on the episode, we mark it as complete. This will tell the server that the episode is complete for that user. However, when we click the back button we'll see that the status still displays incomplete. If we refresh the page, the status now shows completed.

This is because the page is being loaded from the Turbolinks front end cache. We had just clicked the complete button to modify data on the server side, but Turbolinks is not aware of this change. To address this issue, we can modify the behavior of the complete button such that the Turbolinks cache is cleared.

Let's walk through what happens when clicking the complete button. First, the create action of the complete controller is called. This action responds with some JavaScript to update the button, and if the episode is within a series, it is also marked as complete. We can add the following line to the Javascript response (in this example, create.js.erb):

Turbolinks.clearCache();

This line instructs Turbolinks to load the page via server on the next page load. So in the example when we click the back button, the browser is now forced to reload the page via server instead of loading from the Turbolinks cache.

Using clearCache(), we'll see that the episodes page is now loading via server as indicated by the progress bar at the top. The page is no longer loaded from the Turbolinks cache, instead the page is requested again from the server. Users will now see their changes consistently across different requests.

The clearCache() method can be used within JavaScript responses where a resource is modified, i.e., for POST/PATCH/PUT/DELETE requests. Like our example, this will allow the user to see their changes reflected across different pages.

The clearCache() method comes from the Turbolinks Rails gem. The gem overrides the JavaScript behavior of a 302 redirect by adding a couple lines of code. Like we saw above, the first line clears the cache.

script << "Turbolinks.clearCache()"

The second line tells Turbolinks what page to display next.

script << "Turbolinks.visit(#{location.to_json}, #{visit_options.to_json})"

Now with Turbolinks enabled, whenever a redirect is made and the request is a JavaScript request, the two lines are automatically added to the response. This can be verified by inspecting the network tab in the browser's developer tools.

In conclusion, the Turbolinks clearCache() method can improve the user experience by getting rid of the inconsistencies that arise out of loading pages from cache. Thanks for watching and reading!

Written by Frank Lam

Discussion


Gravatar

Does it works only for JS responses? Or it could be used in html responses and how to do that?

Gravatar

It's a Javascript method, so it must be done in Javascript. You only need to call this if data changes during a request. If you're making a POST/PUT/DELETE not via Javascript, you wouldn't need this because your browser will not be loading the next page view JS.


Gravatar

@excid3:disqus As far as I can tell the caching used by turbolinks is not available offline. Do you agree with this?

Gravatar

Well the turbolinks cache is designed to display the previous page quickly before refreshing it with the latest version. It's not designed for offline work, just to speed up the page.

Basecamp's mobile app basically just implements a "The internet connection appears to be offline" for pages and a reload button till the user is back online. ServiceWorkers in HTML5 are designed to help make offline functionality of web pages a bit better, but if it's a mobile app you may also want to build out some views natively so that they still function offline.

Gravatar

Thanks for taking the time to reply. It's worth noting also that ServiceWorkers currently aren't supported on iOS or Android webviews: https://developer.mozilla.o...

So my current conclusion (based on my current knowledge level) is if you want to adopt the "offline first" mentality with your native/hybrid mobile app then avoid Turbolinks 5 and instead look at other solutions (ie fully native in Swift, React Native with Realm, etc).

Gravatar

Yeah Turbolinks is not designed for mobile apps that need to work offline. It has basic fallbacks but it's intention is never to make fully offline mobile apps.

Gravatar

Do you have any thoughts about using an approach like https://github.com/meagar/r... to enable basic caching of assets?

Gravatar

Unfortunately AppCache was deprecated in favor of Service Workers due to some poor design they discovered on more complex apps. https://developer.mozilla.o... has the deprecation warnings at the top there.

Gravatar

Is there anything you don't know?

Gravatar

Hehe 😎 I actually saw that earlier when I was poking around the offline web app stuff on MDN when we were talking about ServiceWorkers. I haven't done a whole lot with stuff though, just dabbled.


Gravatar
Is there anyway to invoke this when moving between layouts? I often (but not always) need a screen refresh when moving from application.html.erb to admin.html.erb (different layout and stylesheets)

Login or create an account to join the conversation.