diff --git a/core/modules/node/config/install/search.page.node_search.yml b/core/modules/node/config/install/search.page.node_search.yml
index 440c135..75d6035 100644
--- a/core/modules/node/config/install/search.page.node_search.yml
+++ b/core/modules/node/config/install/search.page.node_search.yml
@@ -1,12 +1,13 @@
+langcode: en
+status: true
+dependencies:
+  module:
+    - node
 id: node_search
 label: Content
-status: true
-langcode: en
 path: node
 weight: -10
 plugin: node_search
 configuration:
   rankings: {  }
-dependencies:
-  module:
-    - node
+search_help: "<h3>Tips for Content search:</h3>\r\n<ul>\r\n<li>Content search looks for exact, case-insensitive keywords; keywords less than 3 characters long are ignored.</li>\r\n<li>Use upper-case OR to get more results. Example: cat OR dog (content contains either \"cat\" or \"dog\").</li>\r\n<li>You can use upper-case AND to require all words, but this is the same as the default behavior. Example: cat AND dog (same as cat dog, content must contain both \"cat\" and \"dog\").</li>\r\n<li>Use quotes to search for a phrase. Example: \"the cat eats mice\".</li>\r\n<li>You can precede keywords by - to exclude them; you must still have at least one \"positive\" keyword. Example: cat -dog (content must contain cat and cannot contain dog).</li>\r\n</ul>\r\n"
diff --git a/core/modules/search/config/schema/search.schema.yml b/core/modules/search/config/schema/search.schema.yml
index 450c60c..7cc923a 100644
--- a/core/modules/search/config/schema/search.schema.yml
+++ b/core/modules/search/config/schema/search.schema.yml
@@ -86,5 +86,8 @@ search.page.*:
     plugin:
       type: string
       label: 'Plugin'
+    search_help:
+      type: string
+      label: 'Search help'
     configuration:
       type: search.plugin.[%parent.plugin]
diff --git a/core/modules/search/src/Controller/SearchController.php b/core/modules/search/src/Controller/SearchController.php
index 4e79f79..a298f6f 100644
--- a/core/modules/search/src/Controller/SearchController.php
+++ b/core/modules/search/src/Controller/SearchController.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\search\Controller;
 
+use Drupal\Component\Utility\Xss;
 use Drupal\Core\Config\ConfigFactory;
 use Drupal\Core\Controller\ControllerBase;
 use Drupal\search\SearchPageInterface;
@@ -109,17 +110,12 @@ public function view(Request $request, SearchPageInterface $entity) {
       );
     }
 
-    $no_results = t('<ul>
-    <li>Check if your spelling is correct.</li>
-    <li>Remove quotes around phrases to search for each word individually. <em>bike shed</em> will often show more results than <em>&quot;bike shed&quot;</em>.</li>
-    <li>Consider loosening your query with <em>OR</em>. <em>bike OR shed</em> will often show more results than <em>bike shed</em>.</li>
-    </ul>');
     $build['search_results'] = array(
       '#theme' => array('item_list__search_results__' . $plugin->getPluginId(), 'item_list__search_results'),
       '#items' => $results,
       '#empty' => array(
         // @todo Revisit where this help text is added.
-        '#markup' => '<h3>' . $this->t('Your search yielded no results.') . '</h3>' . $no_results,
+        '#markup' => '<h3>' . $this->t('Your search yielded no results.') . '</h3>',
       ),
       '#list_type' => 'ol',
       '#attributes' => array(
@@ -143,6 +139,27 @@ public function view(Request $request, SearchPageInterface $entity) {
   }
 
   /**
+   * Creates a render array for the search help page.
+   *
+   * @param \Symfony\Component\HttpFoundation\Request $request
+   *   The request object.
+   * @param \Drupal\search\SearchPageInterface $entity
+   *   The search page entity.
+   *
+   * @return array
+   *   The search help page.
+   */
+  public function searchHelp(SearchPageInterface $entity) {
+    $build = array();
+
+    $build['search_help'] = array(
+      '#markup' => Xss::filterAdmin($entity->get('search_help')),
+    );
+
+    return $build;
+  }
+
+  /**
    * Redirects to a search page.
    *
    * This is used to redirect from /search to the default search page.
diff --git a/core/modules/search/src/Form/SearchPageForm.php b/core/modules/search/src/Form/SearchPageForm.php
index eab451a..4a2178b 100644
--- a/core/modules/search/src/Form/SearchPageForm.php
+++ b/core/modules/search/src/Form/SearchPageForm.php
@@ -9,6 +9,7 @@
 
 use Drupal\Core\Entity\EntityForm;
 use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Url;
 
 /**
  * Provides a search form for site wide search.
@@ -55,6 +56,7 @@ public function form(array $form, FormStateInterface $form_state) {
       '#size' => 30,
       '#maxlength' => 255,
     );
+
     // processed_keys is used to coordinate keyword passing between other forms
     // that hook into the basic search form.
     $form['basic']['processed_keys'] = array(
@@ -66,6 +68,10 @@ public function form(array $form, FormStateInterface $form_state) {
       '#value' => $this->t('Search'),
     );
 
+    $form['help_link'] = array(
+      '#markup' => \Drupal::linkGenerator()->generate($this->t('Search help'), Url::fromRoute('search.help_' . $this->entity->id())),
+    );
+
     // Allow the plugin to add to or alter the search form.
     $plugin->searchFormAlter($form, $form_state);
 
diff --git a/core/modules/search/src/Form/SearchPageFormBase.php b/core/modules/search/src/Form/SearchPageFormBase.php
index 1f8ab8c..1894917 100644
--- a/core/modules/search/src/Form/SearchPageFormBase.php
+++ b/core/modules/search/src/Form/SearchPageFormBase.php
@@ -113,6 +113,14 @@ public function form(array $form, FormStateInterface $form_state) {
       '#default_value' => $this->entity->getPath(),
       '#maxlength' => '255',
     );
+
+    $form['search_help'] = array(
+      '#type' => 'textarea',
+      '#title' => $this->t('Search help'),
+      '#default_value' => $this->entity->get('search_help'),
+      '#description' => $this->t('This help is displayed on a separate page linked from the search page. Most HTML tags are allowed.'),
+    );
+
     $form['plugin'] = array(
       '#type' => 'value',
       '#value' => $this->entity->get('plugin'),
diff --git a/core/modules/search/src/Routing/SearchPageRoutes.php b/core/modules/search/src/Routing/SearchPageRoutes.php
index c8ff06e..caf9d35 100644
--- a/core/modules/search/src/Routing/SearchPageRoutes.php
+++ b/core/modules/search/src/Routing/SearchPageRoutes.php
@@ -95,6 +95,26 @@ public function routes() {
           ),
         )
       );
+
+      $routes["search.help_$entity_id"] = new Route(
+        '/search/' . $entity->getPath() . '/help',
+        array(
+          '_controller' => 'Drupal\search\Controller\SearchController::searchHelp',
+          '_title' => 'Search help',
+          'entity' => $entity_id,
+        ),
+        array(
+          '_entity_access' => 'entity.view',
+          '_permission' => 'search content',
+        ),
+        array(
+          'parameters' => array(
+            'entity' => array(
+              'type' => 'entity:search_page',
+            ),
+          ),
+        )
+      );
     }
     return $routes;
   }
diff --git a/core/modules/search/src/Tests/SearchAdvancedSearchFormTest.php b/core/modules/search/src/Tests/SearchAdvancedSearchFormTest.php
index 21334c3..09ae01c 100644
--- a/core/modules/search/src/Tests/SearchAdvancedSearchFormTest.php
+++ b/core/modules/search/src/Tests/SearchAdvancedSearchFormTest.php
@@ -62,6 +62,6 @@ function testNodeType() {
     $this->assertText($this->node->label(), 'Basic page node is found with POST query and type:page.');
 
     $this->drupalPostForm('search/node', array_merge($edit, array('type[article]' => 'article')), t('Advanced search'));
-    $this->assertText('bike shed', 'Article node is not found with POST query and type:article.');
+    $this->assertText('search yielded no results', 'Article node is not found with POST query and type:article.');
   }
 }
diff --git a/core/modules/search/src/Tests/SearchPageTextTest.php b/core/modules/search/src/Tests/SearchPageTextTest.php
index 5cb4865..2bafebb 100644
--- a/core/modules/search/src/Tests/SearchPageTextTest.php
+++ b/core/modules/search/src/Tests/SearchPageTextTest.php
@@ -11,7 +11,7 @@
 use Drupal\Component\Utility\Unicode;
 
 /**
- * Tests the bike shed text on no results page, and text on the search page.
+ * Tests the search help text and search page text.
  *
  * @group search
  */
@@ -39,7 +39,7 @@ function testSearchText() {
     $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('search yielded no results');
     $this->assertText(t('Search'));
     $title_source = 'Search for @keywords | Drupal';
     $this->assertTitle(t($title_source, array('@keywords' => Unicode::truncate($search_terms, 60, TRUE, TRUE))), 'Search page title is correct');
@@ -47,6 +47,11 @@ function testSearchText() {
     $this->assertNoText(t('Node'), 'Erroneous translated tab and breadcrumb text is not present');
     $this->assertText(t('Content'), 'Tab and breadcrumb text is present');
 
+    $this->clickLink('Search help');
+    $this->assertText(t('Search help'), 'Correct title is on search help page');
+    $this->assertText(t('Tips for Content search'), 'Correct header is on content search help page');
+    $this->assertText(t('Use upper-case OR to get more results'), 'Correct text is on content search help page');
+
     // Search for a longer text, and see that it is in the title, truncated.
     $edit = array();
     $search_terms = 'Every word is like an unnecessary stain on silence and nothingness.';
@@ -66,6 +71,11 @@ function testSearchText() {
     $this->assertText(t('Search'));
     $this->assertTitle(t($title_source, array('@keywords' => Unicode::truncate($this->searching_user->getUsername(), 60, TRUE, TRUE))));
 
+    $this->clickLink('Search help');
+    $this->assertText(t('Search help'), 'Correct title is on search help page');
+    $this->assertText(t('Tips for User search'), 'Correct header is on user search help page');
+    $this->assertText(t('user names and partial user names'), 'Correct text is on user search help page');
+
     // Test that search keywords containing slashes are correctly loaded
     // from the GET params and displayed in the search form.
     $arg = $this->randomMachineName() . '/' . $this->randomMachineName();
diff --git a/core/modules/user/config/install/search.page.user_search.yml b/core/modules/user/config/install/search.page.user_search.yml
index 50b0113..9dbbe50 100644
--- a/core/modules/user/config/install/search.page.user_search.yml
+++ b/core/modules/user/config/install/search.page.user_search.yml
@@ -1,10 +1,12 @@
+langcode: en
+status: true
+dependencies:
+  module:
+    - user
 id: user_search
 label: Users
-status: true
-langcode: en
 path: user
+weight: 0
 plugin: user_search
 configuration: {  }
-dependencies:
-  module:
-    - user
+search_help: "<h3>Tips for User search:</h3>\r\n<ul>\r\n<li>User search looks for user names and partial user names. Example: mar would match usernames mar, delmar, and maryjane.</li>\r\n<li>You can use * as a wildcard within your keyword. Example: m*r would also match user names mar, delmar, and maryjane.</li>\r\n</ul>\r\n"
