question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Turbo Drive treats external URLs redirected from same-origin URLs as same-origin

See original GitHub issue

According to the Turbo Drive docs https://turbo.hotwired.dev/handbook/drive#setting-a-root-location:

By default, Turbo Drive 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.

However, I have encountered two scenarios where this is not the case:

  1. Form POST request to same-origin returns a 303 redirect response to another domain
  2. An anchor with a link to a same-origin URL returns a 303 redirect response to another domain

In both cases, Turbo Drive attempted to load the external URL, which in my particular case causes a CORS error due to cross-origin requests not being allowed by the external page. I’ve fixed both cases by adding data-turbo=false to the <form> and <a> respectively, but based on the wording of the documentation I would have expected them to both fallback to a full page load.

Is it possible for Turbo Drive to handle redirects in the expected way?

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Reactions:1
  • Comments:17 (4 by maintainers)

github_iconTop GitHub Comments

2reactions
TastyPicommented, Oct 5, 2021

I wanted to leave a more complete workaround for what I’m currently doing, as it sounds like it would be helpful.

We have a POST action that creates a Stripe::Checkout::Session and then respond with a redirect to the session’s URL, which is hosted by Stripe and external to us. This sounds similar to what both @mxlje and @edwinv are doing.

The way I’ve built ours is using a form with Turbo disabled and using 303 See Other as the response code, which redirects POST requests to GET requests. I also had to make sure data-remote was not being set on the form because ujs was also having issues (I forget the exact problem). Code example:

# payments_controller.rb
class PaymentsController
  def create
    session = Stripe::Checkout::Session.create(...)
    redirect_to session.url, status: :see_other
end
<%# views/payments/new.html.erb %>
<%= form_with url: payments_path, method: :post, local: true, data: {turbo: false} do |form| %>
  <%# Any other form fields %>
  <%= form.submit "Checkout" %>
<% end %>

Basically the form is turned into just a standard HTML form since all the magic is disabled. The main issue with this is it isn’t possible to update just the form after an error since it’s just a regular HTML form.

2reactions
mxljecommented, Sep 25, 2021

I have the same problem. In my case I want to redirect users to an external payment provider during the checkout, and the URL has to be generated on the server.

Disabling Turbo technically works, but then I am also losing the ability to disable the button using the turbo events (to prevent double clicking), for example.

My current workaround is to use Stimulus and a turbo stream:

import { Controller } from 'stimulus'

export default class extends Controller {
  static values = {
    url: String
  }

  connect() {
	// add error checking as you see fit
    window.location.href = this.urlValue
  }
}
<%= turbo_stream.update :payment do %>
  <%= tag.div nil, data: {
    controller: "location-href",
    location_href_url_value: @url
  } %>
<% end %>

The page with the button has an empty <div id="payment">, which then receives the controller through the stream. It’s not ideal but it works and for me is better than disabling turbo.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Navigate with Turbo Drive - Hotwire Turbo
By default, Turbo Drive only loads URLs with the same origin—i.e. the same protocol, domain name, and port—as the current document. A visit...
Read more >
Redirects and Google Search | Documentation
Redirecting URLs is the practice of resolving an existing URL to a different one, effectively telling your visitors and Google Search that a ......
Read more >
Code run by redirecting same-origin download to a javascript ...
VULNERABILITY DETAILS When redirecting a same-origin download to a javascript: URL, the code that runs has user activation and bypasses CSP.
Read more >
The Ultimate Guide to Django Redirects - Real Python
In Django, you redirect the user to another URL by returning an instance of ... Location: /redirect-success/ X-Frame-Options: SAMEORIGIN Content-Length: 0.
Read more >
How to prevent IFRAME from redirecting top-level window
<iframe src="url" sandbox="allow-forms allow-scripts"></iframe> ... allow-same-origin allows the document to maintain its origin; allow-scripts allows ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found