diff --git a/core/modules/block/custom_block/custom_block.module b/core/modules/block/custom_block/custom_block.module
index e33ccf6..4ebc5cb 100644
--- a/core/modules/block/custom_block/custom_block.module
+++ b/core/modules/block/custom_block/custom_block.module
@@ -44,17 +44,21 @@ function custom_block_menu_local_tasks(&$data, $router_item, $root_path) {
       );
     }
   }
-}
 
-/**
- * Implements hook_menu_local_actions_alter().
- */
-function custom_block_menu_local_actions_alter(&$actions) {
-  if (isset($actions['local_action_static:custom_block_add_action'])) {
-    foreach (list_themes() as $theme => $theme_info) {
-      if ($theme_info->status) {
-        $actions['local_action_static:custom_block_add_action']['appears_on'][] = "block_admin_display.$theme";
-      }
+  $routes = array_map(function ($theme) {
+    return "block_admin_display.$theme";
+  }, array_keys(list_themes()));
+  if (in_array($router_item['route_name'], $routes)) {
+    // @todo Move to a LocalAction plugin when https://drupal.org/node/2045267
+    //   allows local actions to work with query strings.
+    $item = menu_get_item('block/add');
+    if ($item['access']) {
+      // Add a destination parameter.
+      $item['localized_options']['query']['theme'] = end($router_item['map']);
+      $data['actions']['block/add'] = array(
+        '#theme' => 'menu_local_action',
+        '#link' => $item,
+      );
     }
   }
 }
diff --git a/core/modules/block/custom_block/custom_block.pages.inc b/core/modules/block/custom_block/custom_block.pages.inc
index fee9183..a1a3cac 100644
--- a/core/modules/block/custom_block/custom_block.pages.inc
+++ b/core/modules/block/custom_block/custom_block.pages.inc
@@ -22,16 +22,15 @@
  */
 function template_preprocess_custom_block_add_list(&$variables) {
   $variables['types'] = array();
+  $query = Drupal::request()->query->all();
   foreach ($variables['content'] as $type) {
-    $variables['types'][$type->id] = array();
-    $query = array();
-    if (($destination = drupal_get_destination()) && $destination['destination'] !== current_path()) {
-      // A destination parameter is set other than the current path so we
-      // respect that by adding it to the generated links. If the current path
-      // is returned, we ignore it as we don't want to end up back at block/add.
-      $query = $destination;
-    }
-    $variables['types'][$type->id]['link'] = l($type->label(), 'block/add/' . $type->id(), array('query' => $query));
-    $variables['types'][$type->id]['description'] = filter_xss_admin($type->description);
+    $variables['types'][$type->id()] = array(
+      'link' => Drupal::l($type->label(), 'custom_block_add_form', array('custom_block_type' => $type->id()), array('query' => $query)),
+      'description' => filter_xss_admin($type->description),
+      'title' => $type->label(),
+      'localized_options' => array(
+        'query' => $query,
+      ),
+    );
   }
 }
diff --git a/core/modules/block/custom_block/lib/Drupal/custom_block/Controller/CustomBlockController.php b/core/modules/block/custom_block/lib/Drupal/custom_block/Controller/CustomBlockController.php
index b54a9f5..1bcfa20 100644
--- a/core/modules/block/custom_block/lib/Drupal/custom_block/Controller/CustomBlockController.php
+++ b/core/modules/block/custom_block/lib/Drupal/custom_block/Controller/CustomBlockController.php
@@ -105,7 +105,7 @@ public function addForm(CustomBlockTypeInterface $custom_block_type, Request $re
     $block = $this->customBlockStorage->create(array(
       'type' => $custom_block_type->id()
     ));
-    if (($theme = $request->attributes->get('theme')) && in_array($theme, array_keys(list_themes()))) {
+    if (($theme = $request->query->get('theme')) && in_array($theme, array_keys(list_themes()))) {
       // We have navigated to this page from the block library and will keep track
       // of the theme for redirecting the user to the configuration page for the
       // newly created block in the given theme.
diff --git a/core/modules/block/custom_block/lib/Drupal/custom_block/Tests/CustomBlockTypeTest.php b/core/modules/block/custom_block/lib/Drupal/custom_block/Tests/CustomBlockTypeTest.php
index 9b0dc0b..19c1328 100644
--- a/core/modules/block/custom_block/lib/Drupal/custom_block/Tests/CustomBlockTypeTest.php
+++ b/core/modules/block/custom_block/lib/Drupal/custom_block/Tests/CustomBlockTypeTest.php
@@ -146,29 +146,52 @@ public function testsCustomBlockAddTypes() {
     $type = $this->createCustomBlockType('foo');
     $type = $this->createCustomBlockType('bar');
 
-    // Get the default theme.
-    $theme = $this->container->get('config.factory')->get('system.theme')->get('default');
-
     // Get the custom block storage controller.
     $storage_controller = $this->container
       ->get('entity.manager')
       ->getStorageController('custom_block');
 
-    // Test that adding a block from the 'place blocks' form sends you to the
-    // block configure form.
-    $this->drupalGet('admin/structure/block/list/' . $theme . '/add');
-    $this->clickLink(t('Add custom block'));
-    $this->clickLink('foo');
-    $edit = array('info' => $this->randomName(8));
-    $this->drupalPost(NULL, $edit, t('Save'));
-    $blocks = $storage_controller->loadByProperties(array('info' => $edit['info']));
-    if (!empty($blocks)) {
-      $block = reset($blocks);
-      $destination = 'admin/structure/block/add/custom_block:' . $block->uuid() . '/' . $theme;
-      $this->assertUrl(url($destination, array('absolute' => TRUE)));
-    }
-    else {
-      $this->fail('Could not load created block.');
+    // Enable all themes.
+    theme_enable(array('bartik', 'seven'));
+    $themes = array('bartik', 'seven', 'stark');
+    $theme_settings = $this->container->get('config.factory')->get('system.theme');
+    foreach ($themes as $default_theme) {
+      // Change the default theme.
+      $theme_settings->set('default', $default_theme)->save();
+      menu_router_rebuild();
+
+      // For each enabled theme, go to its block page and test the redirects.
+      $themes = array('bartik', 'stark', 'seven');
+      foreach ($themes as $theme) {
+        // Test that adding a block from the 'place blocks' form sends you to the
+        // block configure form.
+        $path = $theme == $default_theme ? 'admin/structure/block' : "admin/structure/block/list/$theme";
+        $this->drupalGet($path);
+        $this->clickLink(t('Add custom block'));
+        // The seven theme has markup inside the link, we cannot use clickLink().
+        if ($default_theme == 'seven') {
+          $options = $theme != $default_theme ? array('query' => array('theme' => $theme)) : array();
+          $this->assertLinkByHref(url('block/add/foo', $options));
+          $this->drupalGet('block/add/foo', $options);
+        }
+        else {
+          $this->clickLink('foo');
+        }
+        // Create a new block.
+        $edit = array('info' => $this->randomName(8));
+        $this->drupalPost(NULL, $edit, t('Save'));
+        $blocks = $storage_controller->loadByProperties(array('info' => $edit['info']));
+        if (!empty($blocks)) {
+          $block = reset($blocks);
+          $destination = 'admin/structure/block/add/custom_block:' . $block->uuid() . '/' . $theme;
+          $this->assertUrl(url($destination, array('absolute' => TRUE)));
+          $this->drupalPost(NULL, array(), t('Save block'));
+          $this->assertUrl(url("admin/structure/block/list/$theme", array('absolute' => TRUE, 'query' => array('block-placement' => drupal_html_class($theme . '.' . $edit['info'])))));
+        }
+        else {
+          $this->fail('Could not load created block.');
+        }
+      }
     }
 
     // Test that adding a block from the 'custom blocks list' doesn't send you
@@ -180,11 +203,8 @@ public function testsCustomBlockAddTypes() {
     $this->drupalPost(NULL, $edit, t('Save'));
     $blocks = $storage_controller->loadByProperties(array('info' => $edit['info']));
     if (!empty($blocks)) {
-      $block = reset($blocks);
-      $destination = 'admin/structure/block/add/custom_block:' . $block->uuid() . '/' . $theme;
-      $this->assertUrl(url('admin/structure/block/custom-blocks', array(
-        'absolute' => TRUE
-      )));
+      $destination = 'admin/structure/block/custom-blocks';
+      $this->assertUrl(url($destination, array('absolute' => TRUE)));
     }
     else {
       $this->fail('Could not load created block.');
diff --git a/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php b/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php
index 1ebccca..5e32613 100644
--- a/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php
+++ b/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php
@@ -2377,7 +2377,11 @@ protected function assertUrl($path, array $options = array(), $message = '', $gr
       ));
     }
     $options['absolute'] = TRUE;
-    return $this->assertEqual($this->getUrl(), $this->container->get('url_generator')->generateFromPath($path, $options), $message, $group);
+    // Paths in query strings can be encoded or decoded with no functional
+    // difference, decode them for comparison purposes.
+    $actual_url = urldecode($this->getUrl());
+    $expected_url = urldecode($this->container->get('url_generator')->generateFromPath($path, $options));
+    return $this->assertEqual($actual_url, $expected_url, $message, $group);
   }
 
   /**
diff --git a/core/themes/seven/seven.theme b/core/themes/seven/seven.theme
index ceb4ab5..cb0cd84 100644
--- a/core/themes/seven/seven.theme
+++ b/core/themes/seven/seven.theme
@@ -90,16 +90,16 @@ function seven_node_add_list($variables) {
  * Displays the list of available custom block types for creation.
  */
 function seven_custom_block_add_list($variables) {
-  $content = $variables['content'];
   $output = '';
-  if ($content) {
+  if (!empty($variables['types'])) {
     $output = '<ul class="admin-list">';
-    foreach ($content as $type) {
+    foreach ($variables['types'] as $id => $type) {
       $output .= '<li class="clearfix">';
-      $content = '<span class="label">' . check_plain($type->label()) . '</span>';
-      $content .= '<div class="description">' . filter_xss_admin($type->description) . '</div>';
+      $content = '<span class="label">' . check_plain($type['title']) . '</span>';
+      $content .= '<div class="description">' . filter_xss_admin($type['description']) . '</div>';
+      $options = $type['localized_options'];
       $options['html'] = TRUE;
-      $output .= Drupal::l($content, 'custom_block_add_form' , array('custom_block_type' => $type->id()), $options);
+      $output .= Drupal::l($content, 'custom_block_add_form', array('custom_block_type' => $id), $options);
       $output .= '</li>';
     }
     $output .= '</ul>';
