Using setRedirect() for Post-Submission Redirectsfor Drupal 8 , 9 , 10 , and 11

Last updated :  

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.

Gotcha: 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 route entity.node.canonical actually expects a parameter named node, 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 plain setRedirect() 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.