I have a custom module that displays a form.

Upon submitting the form, I want to redirect the user to a different page.

How can I do that?

7 Answers 7


In the submit handler you do

Drupal 7:

$form_state['redirect'] = 'url';

Drupal 8:

$form_state->setRedirect('route', $args, $options);
  • is there an alternative way of doing this? the forms I need to redirect are built with its own #submit handler (the submit handlers are not placed in my custom module), so I don't have access to the code. Commented Jun 26, 2011 at 14:16
  • @Charlie use form_alter to add your own.
    – googletorp
    Commented Jun 26, 2011 at 21:53
  • @Charlie if your for is mainly accessible by a link, put a destination parameter in the URL: /my-form?destination=node/123.
    – tostinni
    Commented Sep 4, 2011 at 4:25
  • Not working on D7, but I found something that does. Check my message below. Commented Sep 1, 2014 at 16:41
  • I just want to say thanks for answering for D7, then coming back 5 years later to update the answer for D8. <3
    – aek
    Commented Feb 15, 2018 at 21:37

It should be noted there are several triggers that may prevent a redirection:

  • $form_state['redirect'] === FALSE: If set, the form builder function or form validation/submit handler does not want a user to be redirected, which means that drupal_goto() is not invoked. For most forms, the redirection logic will be the same regardless of whether $form_state['redirect'] is undefined or FALSE. However, in case it was not defined and the current request contains a 'destination' query string, drupal_goto() will redirect to that given destination instead. Only setting $form_state['redirect'] to FALSE will prevent any redirection.
  • $form_state['no_redirect'] === TRUE: When set, the callback that originally built the form explicitly disallows any redirection, regardless of the redirection value in $form_state['redirect']. For example, ajax_get_form() defines $form_state['no_redirect'] when building a form in an AJAX callback to prevent any redirection. $form_state['no_redirect'] should NOT be altered by form builder functions or form validation/submit handlers.
  • $form_state['programmed'] === TRUE: means the form submission was usually invoked via drupal_form_submit(), so any redirection would break the script that invoked drupal_form_submit().
  • $form_state['rebuild'] === TRUE: means the form needs to be rebuilt without redirection.

For Drupal 7, I tried this on a custom module and it works. It can also be used in a theme:

function my_theme_form_alter(&$form, &$form_state, $form_id) {
  if ($form_id == 'contact_site_form') {
    $form['#submit'][] = 'contact_form_submit_handler';

function contact_form_submit_handler(&$form, &$form_state) {
  $form_state['redirect'] = 'thank-you-page-alias';

BTW, I found this snippet here: https://gist.github.com/postrational/5768796


On D8 i did like this (but this won't work... see below):

* Implements hook_form_FORM_ID_alter().
function MYMODULE_form_FORM_ID_form_alter( array &$form, FormStateInterface $form_state, $form_id ) {

   // Force redirect to "/thankyou" page
   $url = "/thankyou";
   $path = \Drupal::service('path.alias_manager')->getPathByAlias($url);
   if(preg_match('/node\/(\d+)/', $path, $matches)) {
       array('node' => $matches[1])



I was missing that setRedirect/setRedirectUrl works AFTER the module is submitted, so this is my working solution on D8:

use Drupal\Core\Url;

 * Implements hook_form_FORM_ID_alter().
function MYMODULE_form_FORM_ID_form_alter( array &$form, FormStateInterface $form_state, $form_id ) {
  $form['actions']['submit']['#submit'][] = 'MYFORM_redirect_handler';

function MYFORM_redirect_handler($form, FormStateInterface $form_state) {
  // Force redirect to "/sent"
  $dest_url = "/sent";
  $url = Url::fromUri('internal:' . $dest_url);
  $form_state->setRedirectUrl( $url );

Hope this could help

  • 1
    Thank you, this helped me to solve my problem on a multi language site. Now I disable the redirect with $form_state->disableRedirect() in order to avoid the error "Redirects to external URLs are not allowed by default, use \Drupal\Core\Routing\TrustedRedirectResponse for it." Of course it is not an external URL, it is the domain for a different language. This causes a lot of problems in Drupal core when using multiple domains for multiple languages and diffrent entities (e.g. users) have different languages or default langues ...
    – drupalfan
    Commented Jul 6, 2021 at 18:32
  • Your first solution does not work because $form_state is not passed by reference. Like this, the change to the redirect is lost.
    – dxvargas
    Commented Oct 13, 2021 at 14:44

To redirect to an external URL in Drupal 8, use the TrustedRedirectResponse class, as in the following code.

$response = new TrustedRedirectResponse('http://google.co.in');
  • 1
    In case it could help, we need to include this class with the use keyword and its namespace : use Drupal\Core\Routing\TrustedRedirectResponse; Commented Sep 23, 2019 at 9:05

For drupal 7 if you want to redirect to url with params like someurl?param1=1&param2=2

$query = array(
  'param1' => '1',
   'param2' => '2',
$form_state['redirect'] = array(
      'query'    => $query,
      'fragment' => 'hash_fragment',
    $urlfind = Url::fromRoute('moduleName.show');
    $urlfindstring = $urlfind->toString();
    $redirect = new RedirectResponse($urlfindstring);

under the formRoute write the route of your page and by this code it will redirect the form to that perticular page

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.