Skip to content

Redirects

views

Redirect to an internal URL

In a controller, when we return a RedirectResponse instead of a render array, Symfony redirects to the URL specified in the RedirectResponse.

For example:

php
use \Symfony\Component\HttpFoundation\RedirectResponse;

return new RedirectResponse('node/1');

// Or to redirect to the front page of the site.

$url = Url::fromRoute('<front>');
return new RedirectResponse($url->toString());

Redirect in a form

In a form, you can redirect to a route by its name:

php
$form_state->setRedirect('entity.bike_part.canonical', ['bike_part' => $entity->id()]);

Note, you can also redirect to a specific id (anchor) on the page by adding the fragment parameter

php
$form_state->setRedirect('tea_teks_admin.timeline_detail', 
  ['node'=>$parent_nid], 
  ['fragment' => 'milestone-' . $nid,]
);

Or here in submitForm():

php
$url = Url::fromRoute('user_account.user_register', [], ['query' => ['destination' => $shippingUrl]]);
$form_state->setRedirectUrl($url);

Redirect off-site (to a third-party URL)

From https://drupal.stackexchange.com/questions/136641/how-do-i-redirect-to-an-external-url

Redirect to a third-party website with Redirect permanent status. The URL must have an absolute path like http://www.google.com

php
return new RedirectResponse('https://google.com');

e.g.

php
Use Drupal\Core\Routing\TrustedRedirectResponse;

$absolute_url = 'https://google.com';
$response = new RedirectResponse($absolute_url, 301);
//OR
$response = new \Drupal\Core\Routing\TrustedRedirectResponse($absolute_url, 301);
$response->send();

exit(0);

Redirect to an existing route with an anchor (or fragment)

You can specify the route using the route name from your module.routing.yml file.

Note, you can also redirect to a specific id (anchor) on the page by adding the fragment parameter

php
$form_state->setRedirect('tra_teks_admin.timeline_detail', 
  ['node'=>$parent_nid], 
  ['fragment' => 'milestone-' . $nid,]
);

Redirect to a complex route

Here, the route requires four arguments, so they all need to be passed in.

php
$form_state->setRedirectUrl(Url::fromRoute('tra_teks_srp.confidential_voting', [
  'citadel_nid' => $citadel_nid,
  'performance_nid' => $performance_nid,
  'action' => 'vote',
  'type' =>$type,
]));

Redirect in a controller

When you need to send the user to a different page on your site based on some logic, you might use code something like this. Lots of processing happens and if the conditions are met, instead of returning a render array, we return a RedirectResponse and the browser will load that page.

php
protected function reloadOperations(): ?RedirectResponse {
  $program_nid = $this->programNode->id();
  if (substr($this->action, 0, 6) === 'reload') {
    $new_type = substr($action, 7);
    $this->votingProcessor->buildVotingPath($this->programNode, $new_type);
    $valid_voting_path = $this->votingProcessor->loadYourVotingPathFromTempStore($program_nid);
    $empty_voting_path = $this->votingProcessor->isEmptyVotingPath();
    if ($valid_voting_path && $empty_voting_path) {
      // Redirect to kss overview.
      $message = "No eligible items found. Redirected to KSS overview";
      \Drupal::messenger()->addMessage($message);
      $url = Url::fromRoute('tea_teks_srp.kss_overview', [
        'program' => $program_nid,
        'type' => 'all',
        'userid' => $this->persona->getUserId(),
      ]);
      return new RedirectResponse($url->toString());
    }
    if ($valid_voting_path && !$empty_voting_path) {
      //redirect to the first item in the path.
      $item = $this->votingProcessor->getFirstVotingPathItem();
      $vote_type = 'narrative';
      if (empty($item['narrative'])) {
        $vote_type = 'activity';
      }
      $url = Url::fromRoute('tea_teks_srp.correlation_voting', [
        'program' => $program_nid,
        'expectation' => $item['expectation_nid'],
        'correlation' => $item['correlation_nid'],
        'action' => "vote-$new_type",
        'type' => $vote_type,
      ]);
      return new RedirectResponse($url->toString());
    }
  }

Redirect user after login

From: https://www.drupal.org/forum/support/module-development-and-code-questions/2013-08-18/how-to-redirect-user-after-login-in This example checks both the route and user role to conditionally redirect.

php
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Url;

/**
 * Implements hook_user_login().
 */
function greenacorn_user_login(AccountInterface $account) {
  $roles = $account->getRoles();
  $route_name = \Drupal::routeMatch()->getRouteName();
  if ($route_name != 'user.reset.login' && in_array('client', $roles)) 
  {
    $destination = Url::fromUserInput('/my-issues')->toString();
    \Drupal::service('request_stack')->getCurrentRequest()->query->set('destination', $destination);
  }
}

Redirect to the 403 or 404 page

php
// Redirect to the 403 page.
throw new \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException();

// Redirect to the 404 page.
throw new \Symfony\Component\HttpKernel\Exception\NotFoundHttpException();

Redirect to a new page after node operation

This was implemented in a module in a hook_form_alter call. Here we tell the form to call the special handler: cn_submit_handler() function in the form.

php
function obg_mods_form_alter(array &$form, FormStateInterface $form_state, $form_id) {
  $accountProxy = \Drupal::currentUser();
  $account = $accountProxy->getAccount();

  // Add special validation for anonymous users only.
  if (($accountProxy->isAnonymous() && ($form_id == 'node_catastrophe_notice_form'))) {
    $form['#validate'][] = 'cn_form_validate';

    // Submit handler to redirect to /thanks-your-submission.
    foreach (array_keys($form['actions']) as $action) {
      if ($action != 'preview' && isset($form['actions'][$action]['#type']) && $form['actions'][$action]['#type'] === 'submit') {
        $form['actions'][$action]['#submit'][] = 'cn_submit_handler';
      }
    }
  }

And here is the submit handler where the work gets done and you are redirected to /thanks-your-submission.

php
/**
 * Submit handler to redirect user to thank-you page.
 *
 * @param $form
 * @param \Drupal\Core\Form\FormStateInterface $form_state
 */
function cn_submit_handler( $form, FormStateInterface $form_state) {
  $url = Url::fromUri('internal:/thanks-your-submission');
  $form_state->setRedirectUrl($url);
}

More at https://drupal.stackexchange.com/questions/163626/how-to-perform-a-redirect-to-custom-page-after-node-save-or-delete

Redirect dynamically to wherever you came from

In this case, in a form, we grab the referrer URL in the buildForm method using the following code:

php
public function buildForm(array $form, FormStateInterface $form_state, int $program_nid = 0, int $feedback_error_nid = 0, int $citation_nid = 0){
  $form['#theme'] = 'tea_teks_srp__vote_error';

  // Get the referer.
  $request = \Drupal::request();
  $referer = $request->headers->get('referer');
  //$base_url = Request::createFromGlobals()->getSchemeAndHttpHost();
  $base_url = \Drupal::request()->getSchemeAndHttpHost();
  $alias = '';
  if (!is_null($referer)) {
    $alias = substr($referer, strlen($base_url));
  }  
  $form_state->set('referrer_alias', $alias);
  ...
}

Then, in the submitForm() method, once we've completed the work we needed to do, we can redirect back to where we came from using the code below. We can optionally add a fragment which refers to an ID on the page.

php
    $referrer_alias = $form_state->get('referrer_alias');

    // Add the fragment so they drop back on the item they came from.
    $url = Url::fromUri('internal:' . $referrer_alias, ['fragment' => "item_$feedback_error_nid"]);
    $form_state->setRedirectUrl($url);