Symfony & Hotwire Turbo - What HTTP Response To Return When Submitting Forms
These are my personal notes on how to handle forms with Hotwire Turbo in Symfony.
When using GET, return a 200 response
If your form method is GET, you can return a 200 response like normal. Turbo will handle it. So if you're in a controller and return $this->render('response.html.twig') things will operate as you would expect. Turbo will fetch the response using AJAX.
When using POST, return a 303 response
However, if you return $this->render('response.html.twig') on a POST action, Hotwire Turbo will NOT work. Hotwire Turbo expects a 303 Redirect Response. If you use a simple redirect like $this->redirectToRoute('app_success', []) that would work too, but the most turbo way to do it is:
return $this->redirectToRoute('app_success', [], Response::HTTP_SEE_OTHER);
The difference in 302 vs. 303 redirect is this: According to MDN:
302 Found - This response code means that the URI of requested resource has been changed temporarily. Further changes in the URI might be made in the future, so the same URI should be used by the client in future requests.
303 See Other - The server sent this response to direct the client to get the requested resource at another URI with a GET request.
Why doesn't Turbo accept 200s on POST?
From the docs...
The reason Turbo doesn't allow regular rendering on 200's from POST requests is that browsers have built-in behavior for dealing with reloads on POST visits where they present a "Are you sure you want to submit this form again?" dialogue that Turbo can't replicate.