Skip to main

Prefetch Links on hover

  • typescript
  • dom
  • performance
1 min read
export const usePrefetch = (
  { selector, as }: { selector: string; as: string } = {
    selector: "a[data-prefetch]",
    as: "document",
  }
) => {
  window.prefetchedLinks ??= new Set<string>();

  const createPrefetchLink = (url: string) => {
    const link = document.createElement("link");

    link.href = url;
    link.rel = "prefetch";
    link.as = as;
    return link;
  };

  const onHover = (e: Event) => {
    const link = e.target as HTMLAnchorElement;

    if (!window.prefetchedLinks.has(link.href)) {
      window.prefetchedLinks.add(link.href);
      const linkEl = createPrefetchLink(link.href);
      document.head.appendChild(linkEl);
    }
  };

  const prefetchLinks = Array.from(document.querySelectorAll(selector));
  for (let link of prefetchLinks) {
    link.addEventListener("mouseenter", onHover, { once: true, passive: true });
    link.addEventListener("touchstart", onHover, { once: true, passive: true });
  }
};

Usage

<a href="/some-path" data-prefetch>...</a>
<script>
  import { usePrefetch } from "..."; // make sure you have a build step since you can't import TS code :)
  usePrefetch();
</script>