Prefetch Links on hover
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>