Hey Andrew,
I saw the same problem for one of the forms that required me to just redirect to a new page.
From what I saw in the code, Turbo will only redirect on GET requests. I agree with you that this is a pretty strange case and we definitely need a way to say in our form itself that if we get redirected in response, we can do a full redirect. If someone can help with that, would be great!
For now, I did a hack with stimulus. I can share my
import { Controller } from "stimulus"
import { Turbo } from "@hotwired/turbo-rails"
export default class extends Controller {
static targets = [ "form" ]
initialize() {
this.listener = this.listener.bind(this)
}
connect() {
this.formTarget.addEventListener("turbo:submit-end", this.listener)
}
disconnect() {
this.formTarget.removeEventListener("turbo:submit-end", this.listener)
}
listener(event) {
const fetchResponse = event.detail.fetchResponse
if (fetchResponse && fetchResponse.response.status === 201) {
Turbo.visit(fetchResponse.response.headers.get('Url'))
}
}
}
Then in my .erb template I do this for forms where full redirect is required:
<%= turbo_frame_tag 'banana_form' do %>
<%= form_with url: bananas_path, data: { controller: 'redirect-on-created', redirect_on_created_target: 'form' } do |f| %>
<%= f.submit 'Go Bananas' %>
<% end %>
<% end %>
In this case, if your controller will do something like this:
def create
@banana = Banana.new(banana_params)
if @banana.valid?
head :created, url: bananas_path
else
render turbo_stream: turbo_stream.replace('banana_form', partial: 'form')
end
end
So if you will have errors - it will replace your form with a fresh version of partial, if not it will return info for redirect and Turbo will do the job.
I know it’s probably hacky way and I would love Hotwire docs to answer this question for me, but for now, it’s working just fine.