Submit a contact form on most sites and you land on a "thank you" page, not back on the same empty form. That's setRedirect() at work — the mechanism that decides where a visitor's browser goes next once a form submission finishes successfully.
What you'll learn in this lesson
- How to redirect to a named route after submission
- How to pass route parameters along with the redirect
- What happens if you don't call
setRedirect()at all
Redirecting to a route
public function submitForm(array &$form, FormStateInterface $form_state) {
// ... save logic here ...
$form_state->setRedirect('my_module.thank_you_page');
}
setRedirect() takes a route name — the same machine name you'd see as a key in a *.routing.yml file, not a hardcoded URL string. Using the route name instead of a literal path means the redirect keeps working even if the route's actual path changes later.
Passing route parameters
$node = $entity_storage->create(['title' => $title]);
$node->save();
$form_state->setRedirect('entity.node.canonical', ['node' => $node->id()]);
If the target route has a placeholder in its path (like /node/{node}), pass an associative array as the second argument mapping each placeholder name to its real value — here, sending the visitor straight to the node they just created.
What happens with no redirect at all
If submitForm() never calls setRedirect(), Drupal's default behavior is to reload the current page — the same form, freshly rebuilt. For a simple settings form that's often exactly what you want (the user sees their own change reflected immediately); for a "create" form, it usually isn't, since staying on an empty creation form after a successful submit reads as if nothing happened.
setRedirect() only has an effect when the form is reached via a normal full-page request. If the form is invoked through Drupal's AJAX framework, an explicit redirect doesn't navigate the browser the way you'd expect — AJAX-driven forms need an AjaxResponse with a redirect command instead, a different mechanism covered in the AJAX topic.Quick check: you call
$form_state->setRedirect('entity.node.canonical', ['node' => 42])— but the routeentity.node.canonicalactually expects a parameter namednode, and you passed exactly that. What if you'd typo'd the key as'nid'instead? Drupal would throw a routing exception at redirect time, since the route can't resolve a URL without every placeholder it expects — the parameter array keys must exactly match the route's own placeholder names.
Key takeaways
$form_state->setRedirect('route.name', $params)sends the user to a named route, never a hardcoded literal path.- The second argument's array keys must exactly match the target route's placeholder names.
- With no redirect set, Drupal's default is to reload the current form — fine for settings forms, usually wrong for creation forms.
- AJAX-submitted forms need a redirect command inside an
AjaxResponse, not a plainsetRedirect()call.
Coming up next
Not every form needs to save its data to a database table. The next lesson covers a much lighter-weight option — persisting form values straight into Drupal's own configuration system with config.factory.