diff --git a/local/config/vufind/config.ini b/local/config/vufind/config.ini
index 336c633977e56d3869521d78678d4a0b6cff5afd..7a05100d552814eac475fabed2bb29b81175a52d 100644
--- a/local/config/vufind/config.ini
+++ b/local/config/vufind/config.ini
@@ -1552,9 +1552,13 @@ remove[] = "gndmusic"
 ; identifier[replace] is the replacing phrase
 ; identifier[method] calls an alternative method with the link as parameter.
 ;    The method is expected in View\Helper\Root\Record.php
+; identifier[function] calls a function if available with the link as parameter.
+;    The function performed on the url *before* replacing with the replacement. It is 
+;    intended to perform url-encoding links so they can be used as parameter value.
 ; Examples:
 ; url[pattern] = url.pattern.to.resolve.link
 ; url[method]  = resolveLink
+; url[method]  = urlencode (https://www.php.net/manual/de/function.urlencode.php)
 nbn[pattern] = "^urn:nbn:"
 nbn[search]  = "urn:nbn:"
 nbn[replace] = "http://nbn-resolving.de/urn:nbn:"
diff --git a/module/finc/src/finc/Cover/Loader.php b/module/finc/src/finc/Cover/Loader.php
index 672c93a651b7fbe559f76997257c65330d295b72..fe853e9f2e70b56c78ce7c19e6c80b9da8f3e06b 100644
--- a/module/finc/src/finc/Cover/Loader.php
+++ b/module/finc/src/finc/Cover/Loader.php
@@ -59,7 +59,9 @@ class Loader extends \VuFind\Cover\Loader
     public function loadUnavailable()
     {
         $this->hasLoadedUnavailable = true;
-        file_put_contents($this->localFile,self::EMPTY_IMAGE_CONTENT);
+        if ($this->config->Content->useCoverFallbacksOnFail) {
+            file_put_contents($this->localFile, self::EMPTY_IMAGE_CONTENT);
+        }
         return parent::loadUnavailable();
     }
 
diff --git a/module/finc/src/finc/View/Helper/Root/Record.php b/module/finc/src/finc/View/Helper/Root/Record.php
index 7c1968e2b53841e34abaa6262774a7ca4cea5c9a..f326277cf94206114db2980f4b43304b7017742e 100644
--- a/module/finc/src/finc/View/Helper/Root/Record.php
+++ b/module/finc/src/finc/View/Helper/Root/Record.php
@@ -326,55 +326,46 @@ class Record extends \VuFind\View\Helper\Root\Record
     {
         $rewrite = $this->config->LinksRewrite->toArray();
         foreach ($rewrite as $r) {
-            // is pattern set so try rewrite url
-            if (isset($r['pattern']) || $r['remove']) {
-                // is remove pattern than suppress link refs #10834
-                if (isset($r['remove'])) {
-                    if (0 != preg_match(
-                        '/' . addcslashes($r['remove'], '/') . '/i',
-                        trim($link['url'])
-                    )) {
-                        unset($link);
-                        return;
-                    }
+            // is remove pattern than suppress link refs #10834
+            if (isset($r['remove'])) {
+                if (0 != preg_match(
+                    '/' . addcslashes($r['remove'], '/') . '/i',
+                    trim($link['url'])
+                )) {
+                    unset($link);
+                    return;
+                }
+            }
+            // is pattern set and matches so try rewrite url
+            if (isset($r['pattern']) && 0 != preg_match('/' . $r['pattern'] . '/i', trim($link['url']))) {
+                // if function is set and available then perform on url 
+                if (isset($r['function']) && is_callable($r['function'])) {
+                    $link['url'] = $r['function']($link['url']);
                 }
 
                 // is search and replace set so try to rewrite url
                 if (isset($r['search']) && isset($r['replace'])) {
-                    // check if pattern exists. if at least one match than continue
-                    if (0 != preg_match(
-                        '/' . $r['pattern'] . '/i',
-                        trim($link['url'])
-                    )) {
-                        // prepare search pattern
-                        // should be free of conflicting meta characters
-                        $pattern
-                            = str_replace(['.'], ['\.'], $r['search']);
-                        $pattern = '/(' . $pattern . ')/i';
-                        // replace it only one time
-                        $link['url'] = preg_replace(
-                            $pattern,
-                            trim($r['replace']),
-                            trim($link['url']),
-                            1,
-                            $count
-                        );
-                        // add http if needed
-                        // @to-do make it https compatible
-                        if (!preg_match('/^(https?:\/\/)/', $link['url'])) {
-                            $link['url'] = 'http://' . $link['url'];
-                        }
+                    // prepare search pattern
+                    // should be free of conflicting meta characters
+                    $pattern = str_replace(['.'], ['\.'], $r['search']);
+                    $pattern = '/(' . $pattern . ')/i';
+                    // replace it only one time
+                    $link['url'] = preg_replace(
+                        $pattern,
+                        trim($r['replace']),
+                        trim($link['url']),
+                        1,
+                        $count
+                    );
+                    // add http if needed
+                    // @to-do make it https compatible
+                    if (!preg_match('/^(https?:\/\/)/', $link['url'])) {
+                        $link['url'] = 'http://' . $link['url'];
                     }
                 }
                 // is method set so call alternatively method proceed link
                 if (isset($r['method']) && method_exists($this, $r['method'])) {
-                    /* && $count > 0) { @todo fix */
-                    if (0 != preg_match(
-                        '/' . $r['pattern'] . '/i',
-                        trim($link['url'])
-                    )) {
-                        $link['url'] = $this->$r['method']($link['url']);
-                    }
+                    $link['url'] = $this->$r['method']($link['url']);
                 } // end if isset method
             } // end if isset pattern
         } // end foreach
diff --git a/themes/finc/js/covers.js b/themes/finc/js/covers.js
index c251aefba80b034997452c4b1b7103e13847df78..1f150538799ab5778d7129604d192603de5761a5 100644
--- a/themes/finc/js/covers.js
+++ b/themes/finc/js/covers.js
@@ -1,5 +1,5 @@
 /* this is a backport from VF 7 core, remove on upgrade */
-/*global VuFind */
+/* global VuFind */
 function loadCoverByElement(data, element) {
   var url = VuFind.path + '/AJAX/JSON?method=' + 'getRecordCover';
   var img = element.find('img');
@@ -10,10 +10,11 @@ function loadCoverByElement(data, element) {
     spinner.hide();
     container.show();
     if (typeof response.data.url !== 'undefined' && response.data.url !== false) {
-      img.attr("src", response.data.url);
-      container.children().not("img").hide();
+      img.attr('src', response.data.url);
+      container.children().not('img').hide();
       anchor.show();
-      anchor.attr("href", response.data.url);
+      anchor.attr('href', response.data.url);
+      anchor.removeClass('hidden'); // finc specific
     } else {
       img.remove();
       if (typeof response.data.html !== 'undefined') {
@@ -24,9 +25,9 @@ function loadCoverByElement(data, element) {
     }
   }
   $.ajax({
-    dataType: "json",
+    dataType: 'json',
     url: url,
-    method: "GET",
+    method: 'GET',
     data: data,
     element: element,
     success: coverCallback
@@ -44,4 +45,5 @@ function loadCovers() {
     loadCoverByElement(data, $(this));
   });
 }
-$(document).ready(loadCovers);
+// deactivated for finc - we load every single cover directly by itself in cover.phtml
+// $(document).ready(loadCovers);
diff --git a/themes/finc/scss/compiled.scss b/themes/finc/scss/compiled.scss
index 21e429ef2b0d63c2274a376a97ecfae14702a54f..5e7e39fd4fb2dfb0d9a5b422b2a691dc31b3e123 100644
--- a/themes/finc/scss/compiled.scss
+++ b/themes/finc/scss/compiled.scss
@@ -859,6 +859,17 @@ table.collapse.in {
       margin-top: 15px;
     }
   }
+
+  // cover
+  .ajaxcover .spinner {
+    height: 0;
+    position: absolute;
+  }
+
+  .cover-container {
+    min-width: 6em;
+  }
+  // cover - END
 }
 
 //// Sprites for Mediaicons
@@ -1997,8 +2008,8 @@ footer {
 //// access-icon in resultlist
 .result {
   .media-left {
-    min-width: 16%;
     text-align: center;
+    width: 17%;
 
     //// remove left padding for print
     @media print {
diff --git a/themes/finc/templates/RecordDriver/DefaultRecord/result-list.phtml b/themes/finc/templates/RecordDriver/DefaultRecord/result-list.phtml
index 6baef95748b7f8840d8e78a07a38a48c5a700c41..36660cc5e396252fc74e6434b0e0fd971fcc63e4 100644
--- a/themes/finc/templates/RecordDriver/DefaultRecord/result-list.phtml
+++ b/themes/finc/templates/RecordDriver/DefaultRecord/result-list.phtml
@@ -5,6 +5,7 @@ $coverDetails = $this->record($this->driver)->getCoverDetails('result-list', 'me
 $cover = $coverDetails['html'];
 $thumbnail = false;
 $thumbnailAlignment = $this->record($this->driver)->getThumbnailAlignment('result');
+$describedById = $driver->getSourceIdentifier() . '|' . $driver->getUniqueId();
 if ($cover):
   ob_start(); ?>
   <div class="media-<?=$thumbnailAlignment?> <?=$this->escapeHtmlAttr($coverDetails['size'])?>">
@@ -32,7 +33,7 @@ if ($cover):
   <div class="media-body">
     <div class="result-body">
       <div>
-        <a href="<?=$this->recordLink()->getUrl($this->driver)?>" class="title getFull" data-view="<?=$this->params->getOptions()->getListViewOption()?>">
+        <a id="<?=$describedById?>" href="<?=$this->recordLink()->getUrl($this->driver)?>" class="title getFull" data-view="<?=$this->params->getOptions()->getListViewOption()?>">
           <?=$this->record($this->driver)->getTitleHtml()?>
         </a>
       </div>
diff --git a/themes/finc/templates/record/cover.phtml b/themes/finc/templates/record/cover.phtml
index af93f5da6ee32dd07521c4c5006ff8eda9fa2dbc..f8d179eb3f3b9d1e6c246f092509450557a16f84 100644
--- a/themes/finc/templates/record/cover.phtml
+++ b/themes/finc/templates/record/cover.phtml
@@ -10,12 +10,14 @@
 <?php elseif ($cover === false): ?>
   <img src="<?=$this->url('cover-unavailable')?>" <?php if ($linkPreview): ?>data-linkpreview="true" <?php endif; ?>class="nocover" alt="<?=$this->transEsc('No Cover Image')?>" aria-hidden="true" />
 <?php else: ?>
-    <div class="ajaxcover">
-        <div class="spinner"><i class="fa fa-spinner fa-spin"></i> <?=$this->translate('Loading')?>...</div>
+    <div id="cover-<?=$driver->getUniqueID()?>" class="ajaxcover">
+        <div class="spinner"><i class="fa fa-spinner fa-spin"></i></div>
         <div class="cover-container">
-            <a class="coverlink">
-            <img <?php if ($linkPreview): ?>data-linkpreview="true" <?php endif; ?>data-recordsource="<?=$this->escapeHtmlAttr($driver->getSourceIdentifier())?>" data-recordid="<?=$this->escapeHtmlAttr($driver->getUniqueID())?>" data-coversize="<?=$this->escapeHtmlAttr($size)?>" class="recordcover ajax" alt="<?=$this->escapeHtmlAttr($alt); ?>" />
-            </a>
+          <?=$this->render('record/coverReplacement')?>
+          <a class="coverlink hidden">
+            <img src onerror="loadCoverByElement({source:'<?=$this->escapeHtmlAttr($driver->getSourceIdentifier())?>', recordId:'<?=$this->escapeHtmlAttr($driver->getUniqueID())?>', size:'<?=$this->escapeHtmlAttr($size)?>'}, $('#cover-<?=$driver->getUniqueID()?>'))"
+              <?php if ($linkPreview): ?>data-linkpreview="true" <?php endif; ?> class="recordcover ajax" alt="<?=$this->escapeHtmlAttr($alt); ?>" />
+          </a>
         </div>
     </div>
 <?php endif; ?>