Faster Links in React

August 2025 · Derick Zr · 2 minutes read

I clicked a link in my React app. Waited. Watched the spinner.

Then I used Next.js. Links felt instant.

The difference? Prefetching. Next.js loads pages in the background before you click.

I wanted that in my plain React app. Here's how I built it.

The Solution

Build a <PrefetchLink> component that:

  • Prefetches when visible on screen
  • Prefetches on hover (desktop) or touch (mobile)
  • Makes navigation feel instant
import React from "react";
 
const loadedPages = new Set();
 
export function PrefetchLink({ to, loader, children }) {
  let observer;
 
  const setRef = (node) => {
    if (!node) return;
 
    observer = new IntersectionObserver((entries) => {
      if (entries[0].isIntersecting) {
        if (!loadedPages.has(to)) {
          loader();
          loadedPages.add(to);
        }
        observer.disconnect();
      }
    });
 
    observer.observe(node);
  };
 
  const prefetch = () => {
    if (!loadedPages.has(to)) {
      loader();
      loadedPages.add(to);
    }
  };
 
  const handleClick = (e) => {
    e.preventDefault();
    history.pushState(null, "", to);
    window.dispatchEvent(new PopStateEvent("popstate"));
  };
 
  return (
    <a
      href={to}
      ref={setRef}
      onMouseEnter={prefetch}   // desktop
      onTouchStart={prefetch}  // mobile
      onClick={handleClick}
    >
      {children}
    </a>
  );
}

How It Works

Link appears on screen → starts prefetching.

Hover or touch → prefetches immediately.

Click → instant navigation.

Usage

function App() {
  const loadAboutPage = () => import("./AboutPage");
 
  return (
    <PrefetchLink to="/about" loader={loadAboutPage}>
      About Us
    </PrefetchLink>
  );
}

That's it. React links that feel as fast as Next.js.

Faster Links in React