mirror of
				https://github.com/ZetaKebab/quartz.git
				synced 2025-11-04 06:49:49 +00:00 
			
		
		
		
	fix(spa): handle HTML redirects for aliases (#1680)
This commit is contained in:
		@@ -1,5 +1,6 @@
 | 
			
		||||
import { computePosition, flip, inline, shift } from "@floating-ui/dom"
 | 
			
		||||
import { normalizeRelativeURLs } from "../../util/path"
 | 
			
		||||
import { fetchCanonical } from "./util"
 | 
			
		||||
 | 
			
		||||
const p = new DOMParser()
 | 
			
		||||
async function mouseEnterHandler(
 | 
			
		||||
@@ -37,7 +38,7 @@ async function mouseEnterHandler(
 | 
			
		||||
  targetUrl.hash = ""
 | 
			
		||||
  targetUrl.search = ""
 | 
			
		||||
 | 
			
		||||
  const response = await fetch(`${targetUrl}`).catch((err) => {
 | 
			
		||||
  const response = await fetchCanonical(targetUrl).catch((err) => {
 | 
			
		||||
    console.error(err)
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
import micromorph from "micromorph"
 | 
			
		||||
import { FullSlug, RelativeURL, getFullSlug, normalizeRelativeURLs } from "../../util/path"
 | 
			
		||||
import { fetchCanonical } from "./util"
 | 
			
		||||
 | 
			
		||||
// adapted from `micromorph`
 | 
			
		||||
// https://github.com/natemoo-re/micromorph
 | 
			
		||||
@@ -59,7 +60,7 @@ let p: DOMParser
 | 
			
		||||
async function navigate(url: URL, isBack: boolean = false) {
 | 
			
		||||
  startLoading()
 | 
			
		||||
  p = p || new DOMParser()
 | 
			
		||||
  const contents = await fetch(`${url}`)
 | 
			
		||||
  const contents = await fetchCanonical(url)
 | 
			
		||||
    .then((res) => {
 | 
			
		||||
      const contentType = res.headers.get("content-type")
 | 
			
		||||
      if (contentType?.startsWith("text/html")) {
 | 
			
		||||
 
 | 
			
		||||
@@ -24,3 +24,22 @@ export function removeAllChildren(node: HTMLElement) {
 | 
			
		||||
    node.removeChild(node.firstChild)
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AliasRedirect emits HTML redirects which also have the link[rel="canonical"]
 | 
			
		||||
// containing the URL it's redirecting to.
 | 
			
		||||
// Extracting it here with regex is _probably_ faster than parsing the entire HTML
 | 
			
		||||
// with a DOMParser effectively twice (here and later in the SPA code), even if
 | 
			
		||||
// way less robust - we only care about our own generated redirects after all.
 | 
			
		||||
const canonicalRegex = /<link rel="canonical" href="([^"]*)">/
 | 
			
		||||
 | 
			
		||||
export async function fetchCanonical(url: URL): Promise<Response> {
 | 
			
		||||
  const res = await fetch(`${url}`)
 | 
			
		||||
  if (!res.headers.get("content-type")?.startsWith("text/html")) {
 | 
			
		||||
    return res
 | 
			
		||||
  }
 | 
			
		||||
  // reading the body can only be done once, so we need to clone the response
 | 
			
		||||
  // to allow the caller to read it if it's was not a redirect
 | 
			
		||||
  const text = await res.clone().text()
 | 
			
		||||
  const [_, redirect] = text.match(canonicalRegex) ?? []
 | 
			
		||||
  return redirect ? fetch(redirect) : res
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user