Should a hook_form_alter be firing both on render and when an additional submit handler is fired? I am trying to add an additional submit handler to the user login form, to simply redirect users to the page they were on before landing on the login page (/user/login).

I have the following code attempting to store the current path/destination in the $form_state storage which is working as I expected when the original form_alter is run on render as it alters the redirect property of form_state to the previous page.  

However, when the form is submitted, the form_alter is fired again, but this time the form_state storage is empty, thus the current_path/destination is now set to /user/login which is not where the user should be redirected to.

Here is the code I have at the moment, any help would be appreciated as to why the form_alter is run again on form submit:

function MODULE_form_user_login_form_alter(&amp;$form, FormStateInterface $form_state, $form_id) {
  $form['#submit'][] = '_module_custom_user_login_form_submit';
  if (is_null($form_state-&gt;get('redirect_dest'))) {
    $destination = $_SERVER['HTTP_REFERER'];
    $form_state-&gt;set('redirect_dest', $destination);
  }
}

function _module_custom_user_login_form_submit($form, FormStateInterface &amp;$form_state) {
  $destination = $form_state-&gt;get('redirect_dest');
  $form_state-&gt;setRedirect($destination);
}
I think the chain of events is different. The form gets cached with no or the wrong redirect_dest set. Then the form is submitted and redirected to the form itself. This is now a new form build, because you didn't request a rebuild. Only in a rebuild you keep the form_state.

Solution:

Drupal has the feature to redirect built in. Add the destination on the page linking to the user login:

Url::fromRoute('user.login', [], ['query' =&gt; $destination])


Edit (new module):

To add the destination automatically you can use this module:

https://www.drupal.org/sandbox/gnuget/2824414

This is a js solution, so it doesn't interfere with caching. I think in this case you can use a sandbox module, because the site won't break if the js code stops working.