turbolinks / turbolinks-classic

Classic version of Turbolinks. Now deprecated in favor of Turbolinks 5.
MIT License
3.54k stars 428 forks source link

How to detect if the request is a turbolinks request #634

Closed phlegx closed 8 years ago

phlegx commented 8 years ago

Hi!

How can I detect on the controller if the request is a turbolinks request? Any idea?

Thx

Thibaut commented 8 years ago

There is currently no way to detect Turbolinks requests server-side. This is intentional — for simplicity (no if request.turbolinks? all over your codebase), and because Turbolinks needs the entire page to be rendered to work properly (to track assets, update CSRF tokens, update <title>, etc.)

inopinatus commented 7 years ago

When Turbolinks is fetching a page for replacement via AJAX, it sets the X-XHR-Referer header. I've use this server-side as a hint that "turbolinks was probably used", to tune the UX of a particular form.

Upside: it is the common case and good enough for tuning UI behaviour.

Downsides: undocumented; other components could set it; sometimes turbolinks will fallback and fetch a page by built-in navigation rather than an AJAX call, in which case the header is not set. Cannot be relied upon for general behaviour.

Hence:

class ApplicationController < ActionController::Base
  # ...
  def its_probably_turbolinks
    request.headers["X-XHR-Referer"].present?
  end
end

If you really want to be sure, you'll have to fork the gem, set your own private header, and deal with the edge cases.

grosser commented 7 years ago

this seems to work: request.env["HTTP_TURBOLINKS_REFERRER"]

inopinatus commented 7 years ago

@grosser Are you looking at Turbolinks 5? That header is not set in turbolinks-classic.

grosser commented 7 years ago

5

inopinatus commented 7 years ago

For those who visit this thread later, please note, this is not the Turbolinks 5 repository. For turbolinks 2.5, request.headers["X-XHR-Referer"] remains the best available way.