diff --git a/core/modules/contact/src/ContactFormListBuilder.php b/core/modules/contact/src/ContactFormListBuilder.php
index 883ad9a..369249a 100644
--- a/core/modules/contact/src/ContactFormListBuilder.php
+++ b/core/modules/contact/src/ContactFormListBuilder.php
@@ -10,6 +10,8 @@
 use Drupal\Component\Utility\String;
 use Drupal\Core\Config\Entity\ConfigEntityListBuilder;
 use Drupal\Core\Entity\EntityInterface;
+use Drupal\Core\Routing\LinkGeneratorTrait;
+use Drupal\Core\Url;
 
 /**
  * Defines a class to build a listing of contact form entities.
@@ -18,6 +20,8 @@
  */
 class ContactFormListBuilder extends ConfigEntityListBuilder {
 
+  use LinkGeneratorTrait;
+
   /**
    * {@inheritdoc}
    */
@@ -32,13 +36,14 @@ public function buildHeader() {
    * {@inheritdoc}
    */
   public function buildRow(EntityInterface $entity) {
-    $row['form'] = $this->getLabel($entity);
     // Special case the personal form.
     if ($entity->id() == 'personal') {
+      $row['form'] = $this->getLabel($entity);
       $row['recipients'] = t('Selected user');
       $row['selected'] = t('No');
     }
     else {
+      $row['form'] = $this->l($this->getLabel($entity), Url::fromRoute('contact.site_page_form', ['contact_form' => $entity->id()]));
       $row['recipients'] = String::checkPlain(implode(', ', $entity->getRecipients()));
       $default_form = \Drupal::config('contact.settings')->get('default_form');
       $row['selected'] = ($default_form == $entity->id() ? t('Yes') : t('No'));
diff --git a/core/modules/contact/src/Plugin/Block/ContactNavigationBlock.php b/core/modules/contact/src/Plugin/Block/ContactNavigationBlock.php
new file mode 100644
index 0000000..9f0c22e
--- /dev/null
+++ b/core/modules/contact/src/Plugin/Block/ContactNavigationBlock.php
@@ -0,0 +1,233 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\contact\Plugin\Block\ContactNavigationBlock.
+ */
+
+namespace Drupal\contact\Plugin\Block;
+
+use Drupal\Component\Utility\String;
+use Drupal\Core\Block\BlockBase;
+use Drupal\Core\Cache\Cache;
+use Drupal\Core\Config\Entity\ConfigEntityStorageInterface;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
+use Drupal\Core\Session\AccountInterface;
+use Drupal\Core\Url;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Provides a 'Contact forms' block.
+ *
+ * @Block(
+ *   id = "contact_navigation",
+ *   admin_label = @Translation("Contact forms"),
+ *   category = @Translation("Menus")
+ * )
+ */
+class ContactNavigationBlock extends BlockBase implements ContainerFactoryPluginInterface {
+
+  /**
+   * The contact form storage.
+   *
+   * @var \Drupal\Core\Config\Entity\ConfigEntityStorageInterface
+   */
+  protected $storage;
+
+  /**
+   * Constructs a new ContactNavigationBlock instance.
+   *
+   * @param array $configuration
+   *   A configuration array containing information about the plugin instance.
+   * @param string $plugin_id
+   *   The plugin_id for the plugin instance.
+   * @param mixed $plugin_definition
+   *   The plugin implementation definition.
+   * @param \Drupal\Core\Config\Entity\ConfigEntityStorageInterface $storage
+   *   The contact category storage.
+   */
+  public function __construct(array $configuration, $plugin_id, $plugin_definition, ConfigEntityStorageInterface $storage) {
+    parent::__construct($configuration, $plugin_id, $plugin_definition);
+
+    $this->storage = $storage;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+    return new static(
+      $configuration,
+      $plugin_id,
+      $plugin_definition,
+      $container->get('entity.manager')->getStorage('contact_form')
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function defaultConfiguration() {
+    return [
+      'forms' => [],
+      'cache' => ['max_age' => Cache::PERMANENT],
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getCacheTags() {
+    $cache_tags = parent::getCacheTags();
+    if ($forms = array_keys($this->configuration['forms'])) {
+      foreach ($this->storage->loadMultiple($forms) as $form) {
+        $cache_tags = Cache::mergeTags($cache_tags, $form->getCacheTag());
+      }
+    }
+    return $cache_tags;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function getRequiredCacheContexts() {
+    // This blocks must be cached per role: different roles may have access to
+    // contact forms.
+    return ['cache_context.user.roles'];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function blockAccess(AccountInterface $account) {
+    // Only grant access to users with the 'access site-wide contact form'
+    // permission.
+    return $account->hasPermission('access site-wide contact form');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function blockForm($form, FormStateInterface $form_state) {
+    $form['forms'] = [
+      '#type' => 'table',
+      '#header' => [
+        'label' => $this->t('Form'),
+        'display' => $this->t('Display'),
+        'weight' => $this->t('Weight'),
+      ],
+      '#empty' => $this->t('There is no contact forms yet. Create one.'),
+      '#tabledrag' => [
+        [
+          'action' => 'order',
+          'relationship' => 'sibling',
+          'group' => 'weight',
+        ],
+      ],
+    ];
+
+    $contact_forms = $this->configuration['forms'];
+    $rows = [];
+    $min_weight = 0;
+    /** @var \Drupal\contact\ContactFormInterface $contact_form */
+    foreach ($this->storage->loadMultiple() as $id => $contact_form) {
+      // Do not list personal contact form.
+      if ($id == 'personal') {
+        continue;
+      }
+
+      $row_label = $contact_form->label();
+      $row_weight = $contact_form->getWeight();
+      $row_display = TRUE;
+
+      if ($contact_forms) {
+        // Display only selected forms by default if there are any.
+        $row_display = isset($contact_forms[$id]);
+        // Find lowest weight to display selected forms first.
+        if ($min_weight > $row_weight) {
+          $min_weight = $row_weight;
+        }
+      }
+      $row = [
+        'label' => ['#markup' => String::checkPlain($row_label)],
+        'display' => [
+          '#type' => 'checkbox',
+          '#default_value' => $row_display,
+          '#title' => t('Display the @title', ['@title' => $row_label]),
+          '#title_display' => 'invisible',
+        ],
+        // Add weight column.
+        'weight' => [
+          '#type' => 'weight',
+          '#title' => $this->t('Weight for @title', ['@title' => $row_label]),
+          '#title_display' => 'invisible',
+          '#default_value' => $row_weight,
+          '#attributes' => ['class' => ['weight']],
+        ],
+      ];
+      $row['#attributes']['class'][] = 'draggable';
+      $row['#weight'] = $row_weight;
+      $rows[$contact_form->id()] = $row;
+    }
+
+    if ($contact_forms) {
+      // Move selected categories to the top of the list.
+      $min_weight = $min_weight - count($contact_forms);
+      foreach ($contact_forms as $id => $data) {
+        if (isset($rows[$id])) {
+          $rows[$id]['#weight'] = $min_weight;
+          $rows[$id]['weight']['#default_value'] = $min_weight++;
+        }
+      }
+    }
+
+    uasort($rows, '\Drupal\Component\Utility\SortArray::sortByWeightProperty');
+    $form['forms'] += $rows;
+
+    return $form;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function blockValidate($form, FormStateInterface $form_state) {
+    $contact_forms = [];
+    foreach ($form_state->getValue('forms') as $id => $value) {
+      if ($value['display']) {
+        $contact_forms[$id] = $value['weight'];
+      }
+    }
+    if (empty($contact_forms)) {
+      $form_state->setErrorByName('forms', $this->t('At least one category should be selected.'));
+    }
+    $form_state->setValue('forms', $contact_forms);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function blockSubmit($form, FormStateInterface $form_state) {
+    $this->configuration['forms'] = $form_state->getValue('forms');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function build() {
+    $links = [];
+    /** @var \Drupal\contact\ContactFormInterface $contact_form */
+    foreach ($this->storage->loadMultiple(array_keys($this->configuration['forms'])) as $id => $contact_form) {
+      $links[$id] = [
+        '#type' => 'link',
+        '#title' => $contact_form->label(),
+        '#url' => Url::fromRoute('contact.site_page_form', ['contact_form' => $id]),
+      ];
+    }
+    return [
+      '#theme' => 'item_list__contact',
+      '#items' => $links,
+    ];
+  }
+
+}
diff --git a/core/modules/contact/src/Tests/ContactSitewideTest.php b/core/modules/contact/src/Tests/ContactSitewideTest.php
index 7e6207f..26a39d7 100644
--- a/core/modules/contact/src/Tests/ContactSitewideTest.php
+++ b/core/modules/contact/src/Tests/ContactSitewideTest.php
@@ -234,7 +234,7 @@ function testSiteWideContact() {
     // Find out in which row the form we want to add a field to is.
     $i = 0;
     foreach($this->xpath('//table/tbody/tr') as $row) {
-      if (((string)$row->td[0]) == $label) {
+      if (((string)$row->td[0]->a) == $label) {
         break;
       }
       $i++;
