I'm trying to setup a custom submit handler, so I can change the redirect URL after submitting comments. Edit: I just want to send users back to the page they were viewing to begin with, but it's a webform with a couple of route parameters, so I need to save them somehow.

This works (the function is called and I see the debug messages):

function mymodule_form_comment_form_alter(&$form, &$form_state) {
    $form['actions']['submit']['#submit'][] = '_submit_foo';

function _submit_foo(&$form, \Drupal\Core\Form\FormStateInterface $form_state) {
    kint('Hello world!');
    \Drupal::logger( 'foo' )->info('hello world');

This DOESN'T work - i.e. as soon as I add a check on the route:

function mymodule_form_comment_form_alter(&$form, &$form_state) {

    $route_name = \Drupal::routeMatch()->getRouteName();

    if ($route_name == 'entity.webform_submission.canonical') {
        // it's DEFINITELY getting this far!

        kint( 'in conditional' );
        kint( $route_name );
        $form['actions']['submit']['#submit'][] = '_submit_foo';
        kint( $form['actions'] );
  • I know the conditional is being reached, I'm seeing the debug statements.
  • _submit_foo() isn't called
  • user is sent to comment.reply instead

Here's a screenshot of the kint($form['actions']):

enter image description here


  • these comments are shown inside a view block (format - show: content, single contextual filter, also generated from URL), which is placed, in block layout, below webform submissions on the standard entity.webform_submission.canonical route - e.g. URL like /admin/structure/webform/manage/application/submission/123
  • there's also code in HOOK_comment_view_alter that adds a 'user' cache context to the view (because each user has their comments filtered, so doing it by role is not enough) - in any case, I've tried disabling that and clearing cache
  • the comments are in a node that has an entity reference to the webform (in case you're wondering how I've managed to combine comments and webform)
  • comment previews are disabled, and I assume I can rule out that submit action based on the first piece of code working as designed?

2 Answers 2


The comment form sets an #action to the comment.reply route, which will rebuild the form and no longer go inside your condition as the route there is differdnt.

Whatever you're trying to do exactly, you need to find a different way to do it.

  • (Thanks.) All I want is for users to return to the page they were originally on after they comment, but that requires the correct route parameters, so I was trying to pass them along with the form. I've just been trying to do it with $form_state->setFormState() and $form_state->get() - those seem to be wiped too… Is there an easier way? Sep 23, 2018 at 20:41
  • Yes, because form state is only persisted/cached from the first ajax request, the initial/non-ajax submit rebuilds the form from scratch and in the case of comment, it does it on a separate route. What you could try is explicitly add the ?destination query argument to the the current page as $form['#action'], so copy & extend this line: $form['#action'] = $this->url('comment.reply', ['entity_type' => $entity->getEntityTypeId(), 'entity' => $entity->id(), 'field_name' => $field_name]);
    – Berdir
    Sep 24, 2018 at 6:14
  • Thanks - ?destination= works well. I've pasted the code I used elsewhere. Sep 24, 2018 at 18:15

Solution: Berdir pointed out I could just use '?destination' - you don't even need a custom handler. Here's what I did if anyone wants the code - you can make this even shorter just using \Drupal::service('path.current')->getPath(); rather than deconstructing and rebuilding the entire route):

 * Implements hook_form_FORM_ID_alter
 * Remove homepage field from comment admin form
 * Change submit button text when adding comments
function mymodule_form_comment_form_alter(&$form, \Drupal\Core\Form\FormStateInterface &$form_state, $form_id) {

    $valid_routes = [

    $route_name = \Drupal::routeMatch()->getRouteName();

    if ( in_array( $route_name, $valid_routes ) ) {
        $webform            = \Drupal::routeMatch()->getParameter( 'webform' );
        $webform_submission = \Drupal::routeMatch()
                                     ->getParameter( 'webform_submission' )->id();

        $destination_link = \Drupal\Core\Url::fromRoute(
                'webform'            => $webform,
                'webform_submission' => $webform_submission
            ] )->toString();

        $form['#action'] .= '?destination='.$destination_link;

Be aware, as per comments on the API page, if you use the $form_id parameter, it's different depending on the operation.

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.