diff --git a/config/vufind/Primo.ini b/config/vufind/Primo.ini
index 5044fff0ebaaa72a858cc905b4043133b1d0ddec..4d77dcb5c07cd575113557b62a29e474db893528 100644
--- a/config/vufind/Primo.ini
+++ b/config/vufind/Primo.ini
@@ -33,6 +33,11 @@ bulkSize = 20
 ; controls its default state: on (true) or off (false).
 retain_filters_by_default = true
 
+; The filters listed below will be applied to all new searches by default. Omit
+; this setting to have no default filters applied. These differ from hidden
+; filters because they are visible in the UI and may be removed by the user.
+;default_filters[] = "rtype:Books"
+
 ; Primo has a fixed cap on how many results you can page through.  Even though
 ; it may report more results than this number, you can't actually access results
 ; past the limit.  This setting tells VuFind where to cut off its paging mechanism.
diff --git a/config/vufind/Summon.ini b/config/vufind/Summon.ini
index cfa986fd9ffb0b8cdc72db11df7c88cf0c5fdaa7..b3cd8a2565e41883c406c0b94abfa595ae4bbd85 100644
--- a/config/vufind/Summon.ini
+++ b/config/vufind/Summon.ini
@@ -53,6 +53,12 @@ snippets = true
 ; controls its default state: on (true) or off (false).
 retain_filters_by_default = true
 
+; The filters listed below will be applied to all new searches by default. Omit
+; this setting to have no default filters applied. These differ from hidden
+; filters because they are visible in the UI and may be removed by the user.
+;default_filters[] = "IsFullText:true"
+;default_filters[] = "excludeNewspapers:true"
+
 ; Summon has a fixed cap on how many results you can page through.  Even though
 ; it may report more results than this number, you can't actually access results
 ; past the limit.  This setting tells VuFind where to cut off its paging mechanism.
diff --git a/config/vufind/searches.ini b/config/vufind/searches.ini
index ce6461f530995a19d6ce430198226f80544c95cc..ea2dbb372cff4c6f926eb93bf491c31461c8cff6 100644
--- a/config/vufind/searches.ini
+++ b/config/vufind/searches.ini
@@ -65,6 +65,12 @@ snippets = true
 ; controls its default state: on (true) or off (false).
 retain_filters_by_default = true
 
+; The filters listed below will be applied to all new searches by default. Omit
+; this setting to have no default filters applied. These differ from hidden
+; filters because they are visible in the UI and may be removed by the user.
+;default_filters[] = "format:Book"
+;default_filters[] = "institution:MyInstitution"
+
 [Cache]
 ; This controls whether the parsed searchspecs.yaml file will be stored to
 ; improve search performance; legal options are APC (use APC cache), File (store
diff --git a/module/VuFind/src/VuFind/Search/Base/Options.php b/module/VuFind/src/VuFind/Search/Base/Options.php
index cbfd27dc7daeb7fafe6fdad49b1c6e638e3b5fac..e8ba9e61a05fc0388d25dc8f6c89af1b4c18e503 100644
--- a/module/VuFind/src/VuFind/Search/Base/Options.php
+++ b/module/VuFind/src/VuFind/Search/Base/Options.php
@@ -54,6 +54,7 @@ abstract class Options implements TranslatorAwareInterface
     protected $basicHandlers = array();
     protected $specialAdvancedFacets = '';
     protected $retainFiltersByDefault = true;
+    protected $defaultFilters = array();
 
     // Available limit options
     protected $defaultLimit = 20;
@@ -552,6 +553,16 @@ abstract class Options implements TranslatorAwareInterface
         return isset($session->lastView) ? $session->lastView : null;
     }
 
+    /**
+     * Get default filters to apply to an empty search.
+     *
+     * @return array
+     */
+    public function getDefaultFilters()
+    {
+        return $this->defaultFilters;
+    }
+
     /**
      * Should filter settings be retained across searches by default?
      *
diff --git a/module/VuFind/src/VuFind/Search/Base/Params.php b/module/VuFind/src/VuFind/Search/Base/Params.php
index 2202e38344e97a68799f8dc7f826ba43364a97a9..ecf4460732cb599b846ce5e3a3cf3715ce0d3180 100644
--- a/module/VuFind/src/VuFind/Search/Base/Params.php
+++ b/module/VuFind/src/VuFind/Search/Base/Params.php
@@ -87,6 +87,13 @@ class Params implements ServiceLocatorAwareInterface
      */
     protected $serviceLocator;
 
+    /**
+     * Are default filters applied?
+     *
+     * @var bool
+     */
+    protected $defaultsApplied = false;
+
     /**
      * Constructor
      *
@@ -1291,6 +1298,20 @@ class Params implements ServiceLocatorAwareInterface
             }
         }
 
+        // If we don't have the special flag indicating that defaults have
+        // been applied, and if we do have defaults, apply them:
+        if ($request->get('dfApplied')) {
+            $this->defaultsApplied = true;
+        } else {
+            $defaults = $this->getOptions()->getDefaultFilters();
+            if (!empty($defaults)) {
+                foreach ($defaults as $current) {
+                    $this->addFilter($current);
+                }
+                $this->defaultsApplied = true;
+            }
+        }
+
         // Handle range filters:
         $this->initRangeFilters($request);
     }
@@ -1387,6 +1408,13 @@ class Params implements ServiceLocatorAwareInterface
         $this->filterList   = $minified->f;
         $this->searchType   = $minified->ty;
 
+        // Deminified searches will always have defaults already applied;
+        // we don't want to accidentally manipulate them further.
+        $defaults = $this->getOptions()->getDefaultFilters();
+        if (!empty($defaults)) {
+            $this->defaultsApplied = true;
+        }
+
         // Search terms, we need to expand keys
         $this->query = QueryAdapter::deminify($minified->t);
     }
@@ -1580,4 +1608,14 @@ class Params implements ServiceLocatorAwareInterface
         }
         return true;
     }
+
+    /**
+     * Are default filters applied?
+     *
+     * @return bool
+     */
+    public function hasDefaultsApplied()
+    {
+        return $this->defaultsApplied;
+    }
 }
\ No newline at end of file
diff --git a/module/VuFind/src/VuFind/Search/Primo/Options.php b/module/VuFind/src/VuFind/Search/Primo/Options.php
index ed7f4dfcfeeddf995c1781a1f49f8c1cb44f11b4..5ad623e41303251de1f2fb7e9431f01e408a32b9 100644
--- a/module/VuFind/src/VuFind/Search/Primo/Options.php
+++ b/module/VuFind/src/VuFind/Search/Primo/Options.php
@@ -84,6 +84,10 @@ class Options extends \VuFind\Search\Base\Options
             $this->retainFiltersByDefault
                 = $searchSettings->General->retain_filters_by_default;
         }
+        if (isset($searchSettings->General->default_filters)) {
+            $this->defaultFilters = $searchSettings->General->default_filters
+                ->toArray();
+        }
 
         // Result limit:
         if (isset($searchSettings->General->result_limit)) {
diff --git a/module/VuFind/src/VuFind/Search/Solr/Options.php b/module/VuFind/src/VuFind/Search/Solr/Options.php
index d1696ea38ad6b33b188836f212f9dea8dc89a229..7c8cfa57116f7f92615c9dc54ffa6ff4838bcf14 100644
--- a/module/VuFind/src/VuFind/Search/Solr/Options.php
+++ b/module/VuFind/src/VuFind/Search/Solr/Options.php
@@ -84,6 +84,10 @@ class Options extends \VuFind\Search\Base\Options
             $this->retainFiltersByDefault
                 = $searchSettings->General->retain_filters_by_default;
         }
+        if (isset($searchSettings->General->default_filters)) {
+            $this->defaultFilters = $searchSettings->General->default_filters
+                ->toArray();
+        }
         if (isset($searchSettings->Basic_Searches)) {
             foreach ($searchSettings->Basic_Searches as $key => $value) {
                 $this->basicHandlers[$key] = $value;
diff --git a/module/VuFind/src/VuFind/Search/Summon/Options.php b/module/VuFind/src/VuFind/Search/Summon/Options.php
index af2f7a2eaf2e28c514ad40fdb0e7804386755064..05b6e122c68c30ec938026b5eaa6081b2e1f0916 100644
--- a/module/VuFind/src/VuFind/Search/Summon/Options.php
+++ b/module/VuFind/src/VuFind/Search/Summon/Options.php
@@ -106,6 +106,10 @@ class Options extends \VuFind\Search\Base\Options
             $this->retainFiltersByDefault
                 = $searchSettings->General->retain_filters_by_default;
         }
+        if (isset($searchSettings->General->default_filters)) {
+            $this->defaultFilters = $searchSettings->General->default_filters
+                ->toArray();
+        }
         if (isset($searchSettings->General->result_limit)) {
             $this->resultLimit = $searchSettings->General->result_limit;
         }
diff --git a/module/VuFind/src/VuFind/Search/UrlQueryHelper.php b/module/VuFind/src/VuFind/Search/UrlQueryHelper.php
index b7a58e46559b4b5cad90d89aae69a213af7fd007..a8c4dd1ae569e70a8db08df391eb3f6536d445ca 100644
--- a/module/VuFind/src/VuFind/Search/UrlQueryHelper.php
+++ b/module/VuFind/src/VuFind/Search/UrlQueryHelper.php
@@ -222,6 +222,9 @@ class UrlQueryHelper
                 $params['shard'] = $shards;
             }
         }
+        if ($this->params->hasDefaultsApplied()) {
+            $params['dfApplied'] = 1;
+        }
 
         return $params;
     }
diff --git a/themes/blueprint/js/common.js b/themes/blueprint/js/common.js
index bf090280615fc7aff82838600f48849cad524faa..b2e4a582084987eb6ee0b51bfe48c79babae3d99 100644
--- a/themes/blueprint/js/common.js
+++ b/themes/blueprint/js/common.js
@@ -45,6 +45,8 @@ function filterAll(element, formId) {
     }
     $("#" + formId + " :input[type='checkbox'][name='filter[]']")
         .attr('checked', element.checked);
+    $("#" + formId + " :input[type='checkbox'][name='dfApplied']")
+        .attr('checked', element.checked);
 }
 
 function extractParams(str) {
diff --git a/themes/blueprint/templates/combined/results.phtml b/themes/blueprint/templates/combined/results.phtml
index d6da81d63443e6269dcfb716242156b0fa5739e6..a677bdf7138b39b2cc9a3c315de9e79b5aad9239 100644
--- a/themes/blueprint/templates/combined/results.phtml
+++ b/themes/blueprint/templates/combined/results.phtml
@@ -18,6 +18,7 @@
             'searchClassId' => $this->params->getsearchClassId(),
             'checkboxFilters' => $this->params->getCheckboxFacets(),
             'filterList' => $this->params->getFilters(),
+            'hasDefaultsApplied' => $this->params->hasDefaultsApplied(),
             'selectedShards' => $this->params->getSelectedShards()
         )
     );
diff --git a/themes/blueprint/templates/search/advanced/layout.phtml b/themes/blueprint/templates/search/advanced/layout.phtml
index 9dcf8c67fe3ff3d6c21bdc4638cb717180d864f9..8915c9b015cf31123135c7df140c6caf81244fd8 100644
--- a/themes/blueprint/templates/search/advanced/layout.phtml
+++ b/themes/blueprint/templates/search/advanced/layout.phtml
@@ -12,9 +12,10 @@
     if (isset($this->saved) && is_object($this->saved)) {
         $searchDetails = $this->saved->getParams()->getQuery();
         $groups = $searchDetails->getQueries();
+        $hasDefaultsApplied = $this->saved->getParams()->hasDefaultsApplied();
         $searchFilters = $this->saved->getParams()->getFilterList();
     } else {
-        $searchDetails = $searchFilters = $groups = false;
+        $hasDefaultsApplied = $searchDetails = $searchFilters = $groups = false;
     }
 
     // Set up Javascript:
@@ -135,6 +136,9 @@
   </div>
 
   <div class="<?=$this->layoutClass('sidebar')?>">
+    <? if ($hasDefaultsApplied): ?>
+      <input type="hidden" name="dfApplied" value="1" />
+    <? endif ?>
     <? if (!empty($searchFilters)): ?>
       <div class="filterList">
         <h3><?=$this->transEsc("adv_search_filters")?><br/><span>(<?=$this->transEsc("adv_search_select_all")?> <input type="checkbox" checked="checked" onclick="filterAll(this, 'advSearchForm');" />)</span></h3>
diff --git a/themes/blueprint/templates/search/results.phtml b/themes/blueprint/templates/search/results.phtml
index 443e5dfb348bae04dbe44b9c852fe5d396b1d858..5155c3bac84b968a21c64121b021392d3a8f1424 100644
--- a/themes/blueprint/templates/search/results.phtml
+++ b/themes/blueprint/templates/search/results.phtml
@@ -18,6 +18,7 @@
             'searchClassId' => $this->params->getsearchClassId(),
             'checkboxFilters' => $this->params->getCheckboxFacets(),
             'filterList' => $this->params->getFilters(),
+            'hasDefaultsApplied' => $this->params->hasDefaultsApplied(),
             'selectedShards' => $this->params->getSelectedShards()
         )
     );
diff --git a/themes/blueprint/templates/search/searchbox.phtml b/themes/blueprint/templates/search/searchbox.phtml
index 01bbbebfc7490033b91ac1ae71703f27f7e86a4e..53dcc0215bcc58ddcd99e2d37a55f431107cda80 100644
--- a/themes/blueprint/templates/search/searchbox.phtml
+++ b/themes/blueprint/templates/search/searchbox.phtml
@@ -77,7 +77,7 @@
             isset($this->checkboxFilters) && is_array($this->checkboxFilters) ? $this->checkboxFilters : array()
         );
       ?>
-      <? if (!empty($filterDetails)): ?>
+      <? if ($hasDefaultsApplied || !empty($filterDetails)): ?>
         <? $defaultFilterState = $options->getRetainFilterSetting() ? ' checked="checked"' : ''; ?>
         <div class="keepFilters">
           <input type="checkbox"<?=$defaultFilterState?> id="searchFormKeepFilters"/> <label for="searchFormKeepFilters"><?=$this->transEsc("basic_search_keep_filters")?></label>
@@ -86,6 +86,11 @@
               <input id="<?=$this->escapeHtml($current['id'])?>" type="checkbox"<?=$defaultFilterState?> name="filter[]" value="<?=$this->escapeHtml($current['value'])?>" />
               <label for="<?=$this->escapeHtml($current['id'])?>"><?=$this->escapeHtml($current['value'])?></label>
             <? endforeach; ?>
+            <? if ($hasDefaultsApplied): ?>
+              <!-- this is a hidden element that flags whether or not default filters have been applied;
+                   it is intentionally unlabeled, as users are not meant to manipulate it directly. -->
+              <input id="dfApplied" type="checkbox" name="dfApplied" value="1" />
+            <? endif; ?>
           </div>
         </div>
       <? endif; ?>
diff --git a/themes/bootstrap/templates/combined/results.phtml b/themes/bootstrap/templates/combined/results.phtml
index e380f189ade9150000ae8510b715d7f6968c02fa..90b09d91e16393d6aa09b66254228324b10e6d7b 100644
--- a/themes/bootstrap/templates/combined/results.phtml
+++ b/themes/bootstrap/templates/combined/results.phtml
@@ -18,6 +18,7 @@
       'searchClassId' => $this->params->getsearchClassId(),
       'checkboxFilters' => $this->params->getCheckboxFacets(),
       'filterList' => $this->params->getFilters(),
+      'hasDefaultsApplied' => $this->params->hasDefaultsApplied(),
       'selectedShards' => $this->params->getSelectedShards()
     )
   );
diff --git a/themes/bootstrap/templates/search/advanced/layout.phtml b/themes/bootstrap/templates/search/advanced/layout.phtml
index 3b0310c44dcf4473e2b79683a089e64633389eab..fa9ae6d508f8d55571021e7b7e4f43c60de28dc2 100644
--- a/themes/bootstrap/templates/search/advanced/layout.phtml
+++ b/themes/bootstrap/templates/search/advanced/layout.phtml
@@ -13,9 +13,10 @@
   if (isset($this->saved) && is_object($this->saved)) {
     $searchDetails = $this->saved->getParams()->getQuery();
     $groups = $searchDetails->getQueries();
+    $hasDefaultsApplied = $this->saved->getParams()->hasDefaultsApplied();
     $searchFilters = $this->saved->getParams()->getFilterList();
   } else {
-    $searchDetails = $searchFilters = $groups = false;
+    $hasDefaultsApplied = $searchDetails = $searchFilters = $groups = false;
   }
 
   // Set up Javascript:
@@ -58,6 +59,9 @@
   </div>
 
   <div class="<?=$this->layoutClass('sidebar')?>">
+    <? if ($hasDefaultsApplied): ?>
+      <input type="hidden" name="dfApplied" value="1" />
+    <? endif ?>
     <? if (!empty($searchFilters)): ?>
       <div class="filterList">
         <h4><?=$this->transEsc("adv_search_filters")?></h4>
diff --git a/themes/bootstrap/templates/search/results.phtml b/themes/bootstrap/templates/search/results.phtml
index dcf99e6b9d0a8c4a54c81fe3de10fb83aec314ac..71794c83bc3c8473325da8f65b83143dec6bfecf 100644
--- a/themes/bootstrap/templates/search/results.phtml
+++ b/themes/bootstrap/templates/search/results.phtml
@@ -18,6 +18,7 @@
         'searchClassId' => $this->params->getsearchClassId(),
         'checkboxFilters' => $this->params->getCheckboxFacets(),
         'filterList' => $this->params->getFilters(),
+        'hasDefaultsApplied' => $this->params->hasDefaultsApplied(),
         'selectedShards' => $this->params->getSelectedShards()
       )
   );
diff --git a/themes/bootstrap/templates/search/searchbox.phtml b/themes/bootstrap/templates/search/searchbox.phtml
index 7ced9c84e3718cf676e957a01e79927409608410..10f244b85c327d42be746d7b9a08a51fc2bbacbd 100644
--- a/themes/bootstrap/templates/search/searchbox.phtml
+++ b/themes/bootstrap/templates/search/searchbox.phtml
@@ -69,7 +69,7 @@
             isset($this->checkboxFilters) && is_array($this->checkboxFilters) ? $this->checkboxFilters : array()
         );
       ?>
-      <? if (!empty($filterDetails)): ?>
+      <? if ($hasDefaultsApplied || !empty($filterDetails)): ?>
         <? $defaultFilterState = $options->getRetainFilterSetting() ? ' checked="checked"' : ''; ?>
         <label class="checkbox">
           <input onChange="$('.applied-filter').click()" type="checkbox"<?=$defaultFilterState?> id="searchFormKeepFilters"/>
@@ -77,9 +77,14 @@
         </label>
         <div class="hidden">
           <? foreach ($filterDetails as $current): ?>
-            <input id="<?=$this->escapeHtml($current['id'])?>" type="checkbox"<?=$defaultFilterState?> name="filter[]" value="<?=$this->escapeHtml($current['value'])?>" />
+            <input class="applied-filter" id="<?=$this->escapeHtml($current['id'])?>" type="checkbox"<?=$defaultFilterState?> name="filter[]" value="<?=$this->escapeHtml($current['value'])?>" />
             <label for="<?=$this->escapeHtml($current['id'])?>"><?=$this->escapeHtml($current['value'])?></label>
           <? endforeach; ?>
+          <? if ($hasDefaultsApplied): ?>
+            <!-- this is a hidden element that flags whether or not default filters have been applied;
+                 it is intentionally unlabeled, as users are not meant to manipulate it directly. -->
+            <input class="applied-filter" id="dfApplied" type="checkbox" name="dfApplied" value="1" />
+          <? endif; ?>
         </div>
       <? endif; ?>
       <?