What I'm trying to do doesn't work, I still get redirected to /node/{id}:

function hook_form_alter(&$form, $form_state, $form_id) {
  $form['actions']['submit']['#submit'][] = 'callback_set_redirect';
function callback_set_redirect($form, FormStateInterface $form_state) {
  • 1
    This is what I found in /core/modules/node/src/NodeForm.php If saving is an option, privileged users get dedicated form submit buttons to adjust the publishing status while saving in one go. @todo This adjustment makes it close to impossible for contributed modules to integrate with "the Save operation" of this form. Modules need a way to plug themselves into 1) the ::submit() step, and 2) the ::save() step, both decoupled from the pressed form button. – olsav Jul 1 '15 at 20:13
  • You can use [drupal.org/project/rules](Rules) module. – Sumit Aggarwal Nov 24 '16 at 9:26
  • Are you sure that your custom submit function is even called? – Eyal Feb 24 '17 at 18:17
  • It could also be that another submit function overrides your custom redirect later. – Eyal Feb 24 '17 at 18:17

Basically the code will work for submit action alone, but drupal node save form have many actions, I think you would have logged in as admin and trying it, then follow the code below.

if you want this to be work for other actions too, That means login as admin and see the node save button, you will have select option "save and publish" , "save and unpublish". as mentioned

use Drupal\Core\Form\FormStateInterface;

function hook_form_alter(&$form, $form_state, $form_id) {
  foreach (array_keys($form['actions']) as $action) {
    if ($action != 'preview' && isset($form['actions'][$action]['#type']) && $form['actions'][$action]['#type'] === 'submit') {
      $form['actions'][$action]['#submit'][] = 'callback_submit';

function callback_submit($form, FormStateInterface $form_state) {

Using hook_form_alter, you'll need to do two things

1) make sure that it's a node form 2) add a custom submit handler to each submit button.

function mymodule_form_alter(&$form, FormStateInterface $form_state, $form_id) {

  if (isset($form['#entity_type']) && $form['#entity_type'] == 'node') {
    foreach (array_keys($form['actions']) as $action) {
      if ($action != 'preview' && isset($form['actions'][$action]['#type']) && $form['actions'][$action]['#type'] === 'submit') {
        $form['actions'][$action]['#submit'][] = 'mymodule_node_form_submit';

Then for the submit function, you can use whatever logic you want. You can compare with NodeForm::save, where it sends you either to the canonical node page or to the front page based on the current user's access permissions.

If you wanted to change this behavior so that it stays on the current node form, you could do this:

function mymodule_node_form_submit($form, FormStateInterface $form_state) {
  $node = $form_state->getFormObject()->getEntity();
  if ($node->id()) {
    if ($node->access('edit')) {
        ['node' => $node->id()]
    else {

If you want to use your custom landing page, you just replace the redirect with the code you're already using:


Note that this won't override when there is a "destination" $_GET parameter, such as at the /admin/content page.

To remove the destination parameter from the /admin/content page, you'll want to uncheck "destination" checkbox under "Content: Operations links (Operations)" in that views fields.

enter image description here


I had success using Symfony RedirectResponse:

function callback_set_redirect($form, FormStateInterface $form_state) {
  $url = Url::fromRoute("custom.landing.page")->toString();
  $response = new RedirectResponse($url);
  • You should not use a response, since it doesn't allow hover modules to change the redirect, if necessary. – kiamlaluno Jun 30 '15 at 5:23
  • Worked for me, too. – Insasse Jan 26 '18 at 13:05

I can't find anything wrong with the original code so something else is probably amiss. It works fine for me.

However, custom.landing.page must be a defined route and parameters (if there are any) need to be passed in like so:

  $form_state->setRedirect("custom.landing.page", [
    'parameter1' => 42,

See FormState::setRedirect() for details.


I always use the Node Save Redirect module for this functionality. It adds an option to a content type that says "what to do after saving new content".

What is this?

This module provides a method of specifying a location to take the user after saving a piece of content.

  • This module wasn't fully ported to Drupal 8 yet. – dxvargas Nov 1 '17 at 18:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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