diff --git a/core/modules/search/src/Controller/SearchController.php b/core/modules/search/src/Controller/SearchController.php
index 0bb918f..dc7af89 100644
--- a/core/modules/search/src/Controller/SearchController.php
+++ b/core/modules/search/src/Controller/SearchController.php
@@ -79,6 +79,8 @@ public function view(Request $request, SearchPageInterface $entity) {
       $plugin->setSearch($keys, $request->query->all(), $request->attributes->all());
     }
 
+    // Create page title.
+    $build['#title'] = $plugin->suggestedTitle();
     $build['search_form'] = $this->entityFormBuilder()->getForm($entity, 'search');
 
     // Build search results, if keywords or other search parameters are in the
diff --git a/core/modules/search/src/Plugin/SearchInterface.php b/core/modules/search/src/Plugin/SearchInterface.php
index 3c5f76d..3d894ed 100644
--- a/core/modules/search/src/Plugin/SearchInterface.php
+++ b/core/modules/search/src/Plugin/SearchInterface.php
@@ -83,6 +83,14 @@ public function execute();
   public function buildResults();
 
   /**
+   * Provides a suggested title for a page of search results.
+   *
+   * @return string
+   *   The translated suggested page title.
+   */
+  public function suggestedTitle();
+
+  /**
    * Alters the search form when being built for a given plugin.
    *
    * The core search module only invokes this method on active module plugins
diff --git a/core/modules/search/src/Plugin/SearchPluginBase.php b/core/modules/search/src/Plugin/SearchPluginBase.php
index 75d030f..6448542 100644
--- a/core/modules/search/src/Plugin/SearchPluginBase.php
+++ b/core/modules/search/src/Plugin/SearchPluginBase.php
@@ -109,6 +109,19 @@ public function searchFormAlter(array &$form, FormStateInterface $form_state) {
     // Empty default implementation.
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function suggestedTitle() {
+    // If the user entered a search string, truncate it and append it to the
+    // title.
+    if (!empty($this->keywords)) {
+      return $this->t('Search for @keywords', array('@keywords' => truncate_utf8($this->keywords, 180, TRUE, TRUE)));
+    }
+    // Use the default 'Search' title.
+    return $this->t('Search');
+  }
+
   /*
    * {@inheritdoc}
    */
diff --git a/core/modules/search/src/Tests/SearchCommentTest.php b/core/modules/search/src/Tests/SearchCommentTest.php
index 70d8c85..9fb3938 100644
--- a/core/modules/search/src/Tests/SearchCommentTest.php
+++ b/core/modules/search/src/Tests/SearchCommentTest.php
@@ -132,7 +132,7 @@ function testSearchResultsComment() {
 
     // Search for $title.
     $this->drupalPostForm('search/node', $edit, t('Search'));
-    $this->assertNoText($comment_body, 'Comment body text not found in search results.');
+    $this->assertText(t('Your search yielded no results.'));
   }
 
   /**
@@ -226,8 +226,8 @@ function assertCommentAccess($assume_access, $message) {
       $expected_comment_result = $this->assertText($this->comment_subject);
     }
     else {
-      $expected_node_result = $this->assertNoText($this->node->label());
-      $expected_comment_result = $this->assertNoText($this->comment_subject);
+      $expected_node_result = $this->assertText(t('Your search yielded no results.'));
+      $expected_comment_result = $this->assertText(t('Your search yielded no results.'));
     }
     $this->assertTrue($expected_node_result && $expected_comment_result, $message);
   }
diff --git a/core/modules/search/src/Tests/SearchPageTextTest.php b/core/modules/search/src/Tests/SearchPageTextTest.php
index b772977..47d17ed 100644
--- a/core/modules/search/src/Tests/SearchPageTextTest.php
+++ b/core/modules/search/src/Tests/SearchPageTextTest.php
@@ -30,15 +30,16 @@ function testSearchText() {
     $this->drupalGet('search/node');
     $this->assertText(t('Enter your keywords'));
     $this->assertText(t('Search'));
-    $title = t('Search') . ' | Drupal';
-    $this->assertTitle($title, 'Search page title is correct');
+    $this->assertTitle(t('Search') . ' | Drupal', 'Search page title is correct');
 
     $edit = array();
-    $edit['keys'] = 'bike shed ' . $this->randomMachineName();
+    $search_terms = 'bike shed ' . $this->randomMachineName();
+    $edit['keys'] = $search_terms;
     $this->drupalPostForm('search/node', $edit, t('Search'));
     $this->assertText(t('Consider loosening your query with OR. bike OR shed will often show more results than bike shed.'), 'Help text is displayed when search returns no results.');
     $this->assertText(t('Search'));
-    $this->assertTitle($title, 'Search page title is correct');
+    $title_source = 'Search for @keywords | Drupal';
+    $this->assertTitle(t($title_source, array('@keywords' => truncate_utf8($search_terms, 180, TRUE, TRUE))), 'Search page title is correct');
     $this->assertNoText('Node', 'Erroneous tab and breadcrumb text is not present');
     $this->assertNoText(t('Node'), 'Erroneous translated tab and breadcrumb text is not present');
     $this->assertText(t('Content'), 'Tab and breadcrumb text is present');
@@ -46,7 +47,7 @@ function testSearchText() {
     $edit['keys'] = $this->searching_user->getUsername();
     $this->drupalPostForm('search/user', $edit, t('Search'));
     $this->assertText(t('Search'));
-    $this->assertTitle($title, 'Search page title is correct');
+    $this->assertTitle(t($title_source, array('@keywords' => truncate_utf8($this->searching_user->getUsername(), 180, TRUE, TRUE))));
 
     // Test that search keywords containing slashes are correctly loaded
     // from the GET params and displayed in the search form.
diff --git a/core/modules/user/src/Tests/UserSearchTest.php b/core/modules/user/src/Tests/UserSearchTest.php
index cbb2628..4ee0a50 100644
--- a/core/modules/user/src/Tests/UserSearchTest.php
+++ b/core/modules/user/src/Tests/UserSearchTest.php
@@ -32,7 +32,7 @@ function testUserSearch() {
     $keys = $user1->getEmail();
     $edit = array('keys' => $keys);
     $this->drupalPostForm('search/user', $edit, t('Search'));
-    $this->assertNoText($keys, 'Search by email did not work for non-admin user');
+    $this->assertText(t('Your search yielded no results.'), 'Search by email did not work for non-admin user');
     $this->assertText('no results', 'Search by email gave no-match message');
 
     // Verify that a non-matching query gives an appropriate message.
@@ -93,7 +93,7 @@ function testUserSearch() {
     $this->drupalLogin($user1);
     $edit = array('keys' => $blocked_user->getUsername());
     $this->drupalPostForm('search/user', $edit, t('Search'));
-    $this->assertNoText($blocked_user->getUsername(), 'Blocked users are hidden from the user search results.');
+    $this->assertText(t('Your search yielded no results.'), 'Blocked users are hidden from the user search results.');
 
     // Create a user without search permission, and one without user page view
     // permission. Verify that neither one can access the user search page.
