Events and script re-evaluation

InstantClick technically makes your website a single-page application, so there’s no DOMContentLoaded firing on page changes anymore. Because of this, other scripts might need to be tweaked to work correctly with InstantClick.

InstantClick fires four events to provide hooks into the lifecycle of the page:

To listen to an event, for example change, use InstantClick.on:

1
InstantClick.on('change', yourCallback);

You’ll want to call InstantClick.on before InstantClick.init, because the change event is triggered on initial page load too, including when the browser doesn’t support pushState.


If you have a script in the <body> that you wish not to re-evaluate when InstantClick displays a page, add it a data-no-instant attribute.

1
<script data-no-instant>alert("I’m only run once.");</script>

If other scripts conflict with InstantClick, it’s advised to add a data-no-instant attribute to all of them, then to remove each attribute one by one until you find the culprit. You might get an idea on how to solve compatibility problems by checking examples (in CoffeeScript) on the Turbolinks Compatibility site.


For an example, here’s how to make Google Analytics (late 2013 code) work:

1 2 3 4 5 6 7 8 9 10
<script src="instantclick.min.js" data-no-instant></script>
<script data-no-instant>
/* Google Analytics code here, without ga('send', 'pageview') */
 
InstantClick.on('change', function() {
ga('send', 'pageview', location.pathname + location.search);
});
 
InstantClick.init();
</script>

Altering content on receive

Sometimes it’s simpler to alter pages on the fly than to rearchitect your back end for InstantClick. receive allows you to do that.

It gets three arguments: url, body and title.

url is the address of the page received, it includes the hash. It’s read-only.

body is the body object and title is the title text. You can modify those two and return an object with them (or with just one of them to modify only one) if you want to alter pages before they’re displayed.

Here’s an example.

1 2 3 4 5 6 7 8 9 10 11 12
InstantClick.on('receive', function(url, body, title) {
var dont_display = body.querySelector('#dont_display_me_when_loaded_with_instantclick')
if (dont_display) {
dont_display.setAttribute('hidden', '');
}
title += ' (loaded with InstantClick)';
return {
body: body,
title: title
};
});

Keep in mind the body object here is body and not document.body!

When you have more than one callback listening to receive, each subsequent callback will get the last altered content.

If you don’t want to alter the page on receive, either don’t return anything or return false.

Documentation table of contents

Getting started

  • 1. Get started
  • 2. How InstantClick works
  • 3. Preloading
  • 4. Blacklisting
  • 5. Events and script re-evaluation
  • Go further

    Meta