diff --git a/core/modules/forum/forum.module b/core/modules/forum/forum.module
index c2de3c9e0b..f6dcdacb4d 100644
--- a/core/modules/forum/forum.module
+++ b/core/modules/forum/forum.module
@@ -12,6 +12,7 @@
 use Drupal\Core\Url;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Routing\RouteMatchInterface;
+use Drupal\node\NodeInterface;
 use Drupal\taxonomy\VocabularyInterface;
 use Drupal\user\Entity\User;
 
@@ -147,7 +148,7 @@ function forum_entity_bundle_field_info_alter(&$fields, EntityTypeInterface $ent
  *
  * Assigns the forum taxonomy when adding a topic from within a forum.
  */
-function forum_node_presave(EntityInterface $node) {
+function forum_node_presave(NodeInterface $node) {
   if (\Drupal::service('forum_manager')->checkNodeType($node)) {
     // Make sure all fields are set properly:
     $node->icon = !empty($node->icon) ? $node->icon : '';
@@ -157,7 +158,10 @@ function forum_node_presave(EntityInterface $node) {
       if (!$node->isNew()) {
         $old_tid = \Drupal::service('forum.index_storage')->getOriginalTermId($node);
         if ($old_tid && isset($node->forum_tid) && ($node->forum_tid != $old_tid) && !empty($node->shadow)) {
-          // A shadow copy needs to be created. Retain new term and add old term.
+          // A shadow copy needs to be created. Retain new term and add old
+          // term. This requires a new revision, as {forum} is keyed by revision
+          // ID.
+          $node->setNewRevision(TRUE);
           $node->taxonomy_forums[count($node->taxonomy_forums)] = ['target_id' => $old_tid];
         }
       }
@@ -331,6 +335,7 @@ function forum_form_node_form_alter(&$form, FormStateInterface $form_state, $for
       '#description' => t('If you move this topic, you can leave a link in the old forum to the new forum.'),
     ];
     $form['forum_tid'] = ['#type' => 'value', '#value' => $node->forum_tid];
+    $form['#entity_builders'][] = 'forum_node_form_entity_builder';
   }
 
   if (isset($form['taxonomy_forums'])) {
@@ -349,6 +354,15 @@ function forum_form_node_form_alter(&$form, FormStateInterface $form_state, $for
 }
 
 /**
+ * Entity builder for the node edit form.
+ *
+ * @see forum_form_node_form_alter()
+ */
+function forum_node_form_entity_builder($entity_type, NodeInterface $node, &$form, FormStateInterface $form_state) {
+  $node->shadow = $form_state->getValue('shadow');
+}
+
+/**
  * Implements hook_preprocess_HOOK() for block templates.
  */
 function forum_preprocess_block(&$variables) {
@@ -447,7 +461,7 @@ function template_preprocess_forums(&$variables) {
         // them is a shadow copy.
         if ($variables['tid'] != $topic->forum_tid) {
           $variables['topics'][$id]->moved = TRUE;
-          $variables['topics'][$id]->title = $topic->getTitle();
+          $variables['topics'][$id]->title_link = $topic->getTitle();
           $variables['topics'][$id]->message = \Drupal::l(t('This topic has been moved'), new Url('forum.page', ['taxonomy_term' => $topic->forum_tid]));
         }
         else {
diff --git a/core/modules/forum/src/ForumIndexStorage.php b/core/modules/forum/src/ForumIndexStorage.php
index 79945746c1..65b6f10645 100644
--- a/core/modules/forum/src/ForumIndexStorage.php
+++ b/core/modules/forum/src/ForumIndexStorage.php
@@ -80,10 +80,23 @@ public function deleteRevision(NodeInterface $node) {
    * {@inheritdoc}
    */
   public function update(NodeInterface $node) {
-    $this->database->update('forum')
-      ->fields(['tid' => $node->forum_tid])
-      ->condition('vid', $node->getRevisionId())
-      ->execute();
+    if (count($node->forum_tid) > 1) {
+      // If there is more than one value, we're leaving a shadow.
+      // Create a new record.
+      $this->database->insert('forum')
+        ->fields(array(
+          'tid' => $node->forum_tid,
+          'vid' => $node->getRevisionId(),
+          'nid' => $node->id(),
+        ))
+        ->execute();
+    }
+    else {
+      $this->database->update('forum')
+        ->fields(array('tid' => $node->forum_tid))
+        ->condition('vid', $node->getRevisionId())
+        ->execute();
+    }
   }
 
   /**
diff --git a/core/modules/forum/tests/src/Functional/ForumTest.php b/core/modules/forum/tests/src/Functional/ForumTest.php
index 76823a757c..7ad2ca0cc1 100644
--- a/core/modules/forum/tests/src/Functional/ForumTest.php
+++ b/core/modules/forum/tests/src/Functional/ForumTest.php
@@ -633,11 +633,16 @@ private function verifyForums(EntityInterface $node, $admin, $response = 200) {
       $this->assertText(t('Forum topic @title has been updated.', ['@title' => $edit['title[0][value]']]), 'Forum node was edited');
 
       // Verify topic was moved to a different forum.
-      $forum_tid = db_query("SELECT tid FROM {forum} WHERE nid = :nid AND vid = :vid", [
+      $forum_tids = db_query("SELECT tid FROM {forum} WHERE nid = :nid", array(
         ':nid' => $node->id(),
-        ':vid' => $node->getRevisionId(),
-      ])->fetchField();
-      $this->assertTrue($forum_tid == $this->rootForum['tid'], 'The forum topic is linked to a different forum');
+      ))->fetchCol();
+      $expected = [$this->rootForum['tid'], $this->forum['tid']];
+      $difference = array_diff($expected, $forum_tids);
+      $this->assertTrue(empty($difference), 'The forum topic is linked to a different forum and the shadow remains');
+
+      // Verify the shadow topic title is shown.
+      $this->drupalGet('forum/' . $this->forum['tid']);
+      $this->assertRaw($edit['title[0][value]'], 'Shadow topic title is shown');
 
       // Delete forum node.
       $this->drupalPostForm('node/' . $node->id() . '/delete', [], t('Delete'));
