# Turbolinks **Turbolinks® makes navigating your web application faster.** Get the performance benefits of a single-page application without the added complexity of a client-side JavaScript framework. Use HTML to render your views on the server side and link to pages as usual. When you follow a link, Turbolinks automatically fetches the page, swaps in its `
`, and merges its ``, all without incurring the cost of a full page load. ![Turbolinks](https://s3.amazonaws.com/turbolinks-docs/images/turbolinks.gif) ## Features - **Optimizes navigation automatically.** No need to annotate links or specify which parts of the page should change. - **No server-side cooperation necessary.** Respond with full HTML pages, not partial page fragments or JSON. - **Respects the web.** The Back and Reload buttons work just as you’d expect. Search engine-friendly by design. - **Supports mobile apps.** Adapters for [iOS](https://github.com/turbolinks/turbolinks-ios) and [Android](https://github.com/turbolinks/turbolinks-android) let you build hybrid applications using native navigation controls. ## Supported Browsers Turbolinks works in all modern desktop and mobile browsers. It depends on the [HTML5 History API](http://caniuse.com/#search=pushState) and [Window.requestAnimationFrame](http://caniuse.com/#search=requestAnimationFrame). In unsupported browsers, Turbolinks gracefully degrades to standard navigation. ## Installation Include [`dist/turbolinks.js`](dist/turbolinks.js) in your application’s JavaScript bundle. Turbolinks automatically initializes itself when loaded via a standalone ` ``` If you have traditionally placed application scripts at the end of `` for performance reasons, consider using the [` ``` ## Ensuring Specific Pages Trigger a Full Reload You can ensure visits to a certain page will always trigger a full reload by including a `` element in the page’s ``. ```html ... ``` This setting may be useful as a workaround for third-party JavaScript libraries that don’t interact well with Turbolinks page changes. ## Setting a Root Location By default, Turbolinks only loads URLs with the same origin—i.e. the same protocol, domain name, and port—as the current document. A visit to any other URL falls back to a full page load. In some cases, you may want to further scope Turbolinks to a path on the same origin. For example, if your Turbolinks application lives at `/app`, and the non-Turbolinks help site lives at `/help`, links from the app to the help site shouldn’t use Turbolinks. Include a `` element in your pages’ `` to scope Turbolinks to a particular root location. Turbolinks will only load same-origin URLs that are prefixed with this path. ```html ... ``` ## Following Redirects When you visit location `/one` and the server redirects you to location `/two`, you expect the browser’s address bar to display the redirected URL. However, Turbolinks makes requests using `XMLHttpRequest`, which transparently follows redirects. There’s no way for Turbolinks to tell whether a request resulted in a redirect without additional cooperation from the server. To work around this problem, send the `Turbolinks-Location` header in response to a visit that was redirected, and Turbolinks will replace the browser’s topmost history entry with the value you provide. The Turbolinks Rails engine sets `Turbolinks-Location` automatically when using `redirect_to` in response to a Turbolinks visit. ## Redirecting After a Form Submission Submitting an HTML form to the server and redirecting in response is a common pattern in web applications. Standard form submission is similar to navigation, resulting in a full page load. Using Turbolinks you can improve the performance of form submission without complicating your server-side code. Instead of submitting forms normally, submit them with XHR. In response to an XHR submit on the server, return JavaScript that performs a [`Turbolinks.visit`](#turbolinksvisit) to be evaluated by the browser. If form submission results in a state change on the server that affects cached pages, consider clearing Turbolinks’ cache with [`Turbolinks.clearCache()`](#turbolinksclearcache). The Turbolinks Rails engine performs this optimization automatically for non-GET XHR requests that redirect with the `redirect_to` helper. ## Setting Custom HTTP Headers You can observe the `turbolinks:request-start` event to set custom headers on Turbolinks requests. Access the request’s XMLHttpRequest object via `event.data.xhr`, then call the [`setRequestHeader`](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest) method as many times as you wish. For example, you might want to include a request ID with every Turbolinks link click and programmatic visit. ```javascript document.addEventListener("turbolinks:request-start", function(event) { var xhr = event.data.xhr xhr.setRequestHeader("X-Request-Id", "123...") }) ``` # API Reference ## Turbolinks.visit Usage: ```js Turbolinks.visit(location) Turbolinks.visit(location, { action: action }) ``` Performs an [Application Visit](#application-visits) to the given _location_ (a string containing a URL or path) with the specified _action_ (a string, either `"advance"` or `"replace"`). If _location_ is a cross-origin URL, or falls outside of the specified root (see [Setting a Root Location](#setting-a-root-location)), or if the value of [`Turbolinks.supported`](#turbolinkssupported) is `false`, Turbolinks performs a full page load by setting `window.location`. If _action_ is unspecified, Turbolinks assumes a value of `"advance"`. Before performing the visit, Turbolinks fires a `turbolinks:before-visit` event on `document`. Your application can listen for this event and cancel the visit with `event.preventDefault()` (see [Canceling Visits Before They Start](#canceling-visits-before-they-start)). ## Turbolinks.clearCache Usage: ```js Turbolinks.clearCache() ``` Removes all entries from the Turbolinks page cache. Call this when state has changed on the server that may affect cached pages. ## Turbolinks.setProgressBarDelay Usage: ```js Turbolinks.setProgressBarDelay(delayInMilliseconds) ``` Sets the delay after which the [progress bar](#displaying-progress) will appear during navigation, in milliseconds. The progress bar appears after 500ms by default. Note that this method has no effect when used with the iOS or Android adapters. ## Turbolinks.supported Usage: ```js if (Turbolinks.supported) { // ... } ``` Detects whether Turbolinks is supported in the current browser (see [Supported Browsers](#supported-browsers)). ## Full List of Events Turbolinks emits events that allow you to track the navigation lifecycle and respond to page loading. Except where noted, Turbolinks fires events on the `document` object. * `turbolinks:click` fires when you click a Turbolinks-enabled link. The clicked element is the event target. Access the requested location with `event.data.url`. Cancel this event to let the click fall through to the browser as normal navigation. * `turbolinks:before-visit` fires before visiting a location, except when navigating by history. Access the requested location with `event.data.url`. Cancel this event to prevent navigation. * `turbolinks:visit` fires immediately after a visit starts. * `turbolinks:request-start` fires before Turbolinks issues a network request to fetch the page. Access the XMLHttpRequest object with `event.data.xhr`. * `turbolinks:request-end` fires after the network request completes. Access the XMLHttpRequest object with `event.data.xhr`. * `turbolinks:before-cache` fires before Turbolinks saves the current page to cache. * `turbolinks:before-render` fires before rendering the page. Access the new `` element with `event.data.newBody`. * `turbolinks:render` fires after Turbolinks renders the page. This event fires twice during an application visit to a cached location: once after rendering the cached version, and again after rendering the fresh version. * `turbolinks:load` fires once after the initial page load, and again after every Turbolinks visit. Access visit timing metrics with the `event.data.timing` object. # Contributing to Turbolinks Turbolinks is open-source software, freely distributable under the terms of an [MIT-style license](LICENSE). The [source code is hosted on GitHub](https://github.com/turbolinks/turbolinks). Development is sponsored by [Basecamp](https://basecamp.com/). We welcome contributions in the form of bug reports, pull requests, or thoughtful discussions in the [GitHub issue tracker](https://github.com/turbolinks/turbolinks/issues). Please note that this project is released with a [Contributor Code of Conduct](CONDUCT.md). By participating in this project you agree to abide by its terms. ## Building From Source Turbolinks is written in [CoffeeScript](https://github.com/jashkenas/coffee-script) and compiled to JavaScript with [Blade](https://github.com/javan/blade). To build from source you’ll need a recent version of Ruby. From the root of your Turbolinks directory, issue the following commands to build the distributable files in `dist/`: ``` $ gem install bundler $ bundle install $ bin/blade build ``` ## Running Tests The Turbolinks test suite is written in [TypeScript](https://www.typescriptlang.org) with the [Intern testing library](https://theintern.io). To run the tests, first make sure you have the [Yarn package manager](https://yarnpkg.com) installed. Follow the instructions for _Building From Source_ above, then run the following commands: ``` $ cd test $ yarn install $ yarn test ``` If you are testing changes to the Turbolinks source, remember to run `bin/blade build` before each test run. --- © 2018 Basecamp, LLC.