I'm attempting to upgrade to Turbo from Turbolinks and I've found that the client is not rendering redirects for form submissions.
Versions:
- rails 6.1.4
- hotwire-rails 0.1.2
- @hotwired/turbo-rails 7.0.0-beta.8
I've ignored the incompatibility between Turbo and Devise for now - just trying to get regular forms working without having to disable Turbo on them.
Here's an example action:
def update
authorize @label
@label.update(label_params)
if @label.save
redirect_to document_labels_path(document_id: @document.id)
else
render :new, status: :unprocessable_entity
end
end
Here's a rendered form:
<form class="simple_form new_label" id="label_form" novalidate="novalidate" action="/documents/72/labels" accept-charset="UTF-8" method="post">
...
</form>
When submitting a valid form, the server will say Processing by LabelsController#create as TURBO_STREAM
and correctly serve a 302. It will then serve the 200 for the redirect location. The browser however is left just looking at the submitted form. Changing the redirect status to 303 doesn't change anything.
I added a console.log for every Turbo event:
document.addEventListener("turbo:load", function () {
console.log('TURBO:LOAD')
})
document.addEventListener("turbo:click", function () {
console.log('TURBO:CLICK')
})
document.addEventListener("turbo:before-visit", function () {
console.log('TURBO:BEFORE-VISIT')
})
document.addEventListener("turbo:visit", function () {
console.log('TURBO:VISIT')
})
document.addEventListener("turbo:submit-start", function () {
console.log('TURBO:SUBMIT-START')
})
document.addEventListener("turbo:before-fetch-request", function () {
console.log('TURBO:BEFORE-FETCH-REQUEST')
})
document.addEventListener("turbo:before-fetch-response", function () {
console.log('TURBO:BEFORE-FETCH-RESPONSE')
})
document.addEventListener("turbo:submit-end", function (event) {
console.log('TURBO:SUBMIT-END')
// event.detail
})
document.addEventListener("turbo:before-cache", function () {
console.log('TURBO:BEFORE-CACHE')
})
document.addEventListener("turbo:before-stream-render", function () {
console.log('TURBO:BEFORE-STREAM-RENDER')
})
document.addEventListener("turbo:render", function () {
console.log('TURBO:RENDER')
})
This is what the output is for a successful form submission:
TURBO:BEFORE-FETCH-REQUEST
TURBO:SUBMIT-START
TURBO:BEFORE-FETCH-RESPONSE
TURBO:SUBMIT-END
There is no render event. Investigating event.detail.fetchResponse.response
for turbo:submit-end
it seems to be perfectly aware that the client should redirect, it just didn't.
Response {type: "basic", url: "http://lvh.me:3000/documents/72/labels", redirected: true, status: 200, ok: true, …}
body: (...)
bodyUsed: true
headers: Headers {}
ok: true
redirected: true
status: 200
statusText: "OK"
type: "basic"
url: "http://lvh.me:3000/documents/72/labels"
__proto__: Response
Update: It is actually performing the redirect and the server is generating the response. The issue is that the client is not rendering the redirect response.