diff --git a/assets/base.scss b/assets/base.scss
index 6f47da3..a462a33 100644
--- a/assets/base.scss
+++ b/assets/base.scss
@@ -470,7 +470,7 @@ header {
 .popover {
   z-index: 999;
   position: absolute;
-  width: 15em;
+  width: 20em;
   display: inline-block;
   visibility: hidden;
   background-color: var(--light);
@@ -491,11 +491,18 @@ header {
   }
 
   & > h3 {
-    margin: 0.5em 0;
+    font-size: 1rem;
+    margin: 0.25em 0;
+  }
+
+  & > .meta {
+    margin-top: 0.25em;
+    opacity: 0.5;
   }
 
   & > p {
     margin: 0;
     font-weight: 400;
+    user-select: none;
   }
 }
diff --git a/config.toml b/config.toml
index 01d8d3d..5c4dfcb 100644
--- a/config.toml
+++ b/config.toml
@@ -2,7 +2,7 @@ baseURL = "https://quartz.jzhao.xyz/"
 languageCode = "en-us"
 googleAnalytics = "G-XYFD95KB4J"
 pygmentsUseClasses = true
-relativeURLs = true
+relativeURLs = false
 disablePathToLower = true
 ignoreFiles = [
     "/content/templates/*",
diff --git a/layouts/_default/_markup/render-link.html b/layouts/_default/_markup/render-link.html
index 2bde76c..c720c45 100644
--- a/layouts/_default/_markup/render-link.html
+++ b/layouts/_default/_markup/render-link.html
@@ -5,5 +5,6 @@
 <a href="{{ $trimmed }}" rel="noopener">{{ .Text | safeHTML }}</a>
 {{- else -}}
 {{$fixedUrl := (cond (hasPrefix $trimmed "/") $trimmed (print "/" $trimmed)) | urlize}}
-<a href="{{$fixedUrl}}" rel="noopener" class="internal-link" data-src="{{$fixedUrl}}">{{ .Text | safeHTML }}</a>
+{{$rooted := strings.TrimRight "/" (.Page.GetPage $fixedUrl).RelPermalink }}
+<a href="{{$rooted}}" rel="noopener" class="internal-link" data-src="{{$rooted}}">{{ .Text | safeHTML }}</a>
 {{- end -}}
\ No newline at end of file
diff --git a/layouts/partials/head.html b/layouts/partials/head.html
index 7ab5aea..1afa3c6 100644
--- a/layouts/partials/head.html
+++ b/layouts/partials/head.html
@@ -26,24 +26,33 @@
 
     <!--  Preload page vars  -->
     <script>
-    const fetchData = async () => {
-      const promises = [
-        fetch("/linkIndex.json")
-          .then(data => data.json())
-          .then(data => ({
-            index: data.index,
-            links: data.links,
-          })),
-        fetch("/contentIndex.json")
-          .then(data => data.json()),
-      ]
-      const [{index, links}, content] = await Promise.all(promises)
-      return ({
-        index,
-        links,
-        content,
-      })
-    }
+      let saved = false
+      const fetchData = async () => {
+        if (saved) {
+          return saved
+        } else {
+          const promises = [
+            fetch("{{ .Site.BaseURL }}/linkIndex.json")
+              .then(data => data.json())
+              .then(data => ({
+                index: data.index,
+                links: data.links,
+              })),
+            fetch("{{ .Site.BaseURL }}/contentIndex.json")
+              .then(data => data.json()),
+          ]
+          const [{index, links}, content] = await Promise.all(promises)
+          const res = ({
+            index,
+            links,
+            content,
+          })
+          saved = res
+          return res
+        }
+
+      }
+      fetchData()
     </script>
 </head>
 {{ template "_internal/google_analytics.html" . }}
diff --git a/layouts/partials/popover.html b/layouts/partials/popover.html
index 35f0738..37f0db4 100644
--- a/layouts/partials/popover.html
+++ b/layouts/partials/popover.html
@@ -1,37 +1,38 @@
 {{if $.Site.Data.config.enableLinkPreview}}
 <script>
-async function run() {
-  const {content} = await fetchData()
   function htmlToElement(html) {
     const template = document.createElement('template')
     html = html.trim()
     template.innerHTML = html
     return template.content.firstChild
   }
-
-  const pathRegex = /\.\.?(\/\.\.)*/
+  const baseUrl = {{strings.TrimRight "/" .Site.BaseURL }}.replace(window.location.origin, "")
   document.addEventListener("DOMContentLoaded", () => {
-    [...document.getElementsByClassName("internal-link")]
-      .forEach(li => {
-        const linkDest = content[li.dataset.src.replace(pathRegex, '')]
-        if (linkDest) {
-          const popoverElement = `<div class="popover">
+    fetchData().then(({content}) => {
+      const links = [...document.getElementsByClassName("internal-link")]
+      links.forEach(li => {
+        console.log(li.dataset.src.replace(baseUrl, ""))
+        console.log(content[li.dataset.src.replace(baseUrl, "")])
+        console.log(content)
+        const linkDest = content[li.dataset.src.replace(baseUrl, "")]
+        // const linkDest = content[li.dataset.src]
+          if (linkDest) {
+            const popoverElement = `<div class="popover">
     <h3>${linkDest.title}</h3>
-    <p>${removeMarkdown(linkDest.content).split(" ", 15).join(" ")}...</p>
+    <p>${removeMarkdown(linkDest.content).split(" ", 20).join(" ")}...</p>
+    <p class="meta">${new Date(linkDest.lastmodified).toLocaleDateString()}</p>
 </div>`
-          const el = htmlToElement(popoverElement)
-          li.appendChild(el)
-          li.addEventListener("mouseover", () => {
-            el.classList.add("visible")
-          })
-          li.addEventListener("mouseout", () => {
-            el.classList.remove("visible")
-          })
-        }
-      })
+            const el = htmlToElement(popoverElement)
+            li.appendChild(el)
+            li.addEventListener("mouseover", () => {
+              el.classList.add("visible")
+            })
+            li.addEventListener("mouseout", () => {
+              el.classList.remove("visible")
+            })
+          }
+        })
+    })
   })
-}
-
-run()
 </script>
 {{end}}
\ No newline at end of file