DEV Community

Cover image for Building a React Hook That Predicts User Navigation Based on Hover Patterns
HexShift
HexShift

Posted on

Building a React Hook That Predicts User Navigation Based on Hover Patterns

Imagine if your app could prefetch pages based on what the user is likely to click — before they actually click it. In this guide, we’ll build a React hook that predicts user navigation based on hover behavior, making your app feel faster without wasteful network calls.

Why Predict Navigation?

Real-world advantages:

  • Prefetching assets and data just-in-time
  • Reducing Time to Interactive (TTI) on key page transitions
  • Enhancing perceived performance for mobile users

Step 1: Build the useHoverIntent Hook

Track hover timing to predict serious "intent" (vs accidental hover):

// useHoverIntent.js
import { useState, useEffect, useRef } from "react";

export function useHoverIntent(onIntent, delay = 150) {
  const timer = useRef(null);

  const onMouseEnter = () => {
    timer.current = setTimeout(() => {
      onIntent();
    }, delay);
  };

  const onMouseLeave = () => {
    clearTimeout(timer.current);
  };

  return {
    onMouseEnter,
    onMouseLeave,
  };
}

Step 2: Create a usePrefetchOnHover Hook

This hook wires hover intent to a custom prefetch action:

// usePrefetchOnHover.js
import { useHoverIntent } from "./useHoverIntent";

export function usePrefetchOnHover(url, prefetchFn) {
  return useHoverIntent(() => {
    prefetchFn(url);
  });
}

Step 3: Create a Prefetching Function

You can customize prefetching depending on your setup (e.g., Next.js, Remix, custom APIs):

// prefetch.js
export async function prefetch(url) {
  try {
    await fetch(url, { method: "HEAD" }); // Lightweight pre-request
  } catch (err) {
    console.error("Prefetch failed:", err);
  }
}

Step 4: Use It Inside a Link Component

// SmartLink.js
import { usePrefetchOnHover } from "./usePrefetchOnHover";
import { prefetch } from "./prefetch";

function SmartLink({ href, children }) {
  const hoverHandlers = usePrefetchOnHover(href, prefetch);

  return (
    <a href={href} {...hoverHandlers}>
      {children}
    </a>
  );
}

export default SmartLink;

Step 5: Put It Together

// App.js
import SmartLink from "./SmartLink";

function App() {
  return (
    <nav>
      <SmartLink href="/about">About Us</SmartLink>
      <SmartLink href="/services">Services</SmartLink>
      <SmartLink href="/contact">Contact</SmartLink>
    </nav>
  );
}

export default App;

Pros and Cons

✅ Pros

  • Predicts real user behavior without AI/ML overhead
  • Prefetches only when there's strong "click intent"
  • Extremely lightweight (one tiny hook)

⚠️ Cons

  • Prefetch timing is tricky — too early = wasted bandwidth, too late = no perceived gain
  • May trigger unnecessary loads if users hover and bounce away often
  • Requires careful UX tuning on mobile (where "hover" can behave differently)

🚀 Alternatives

  • Next.js Link prefetch: Built-in link prefetching on hover (but less customizable)
  • Quicklink: Google Chrome Labs library that auto-prefetches visible links

Summary

Smart prefetching based on hover intent is a secret weapon for frontend performance. With just a few lines of custom React hooks, you can predict where users will go next — and make your app feel instant without wasting resources.

If you found this useful, you can support me here: buymeacoffee.com/hexshift

Image of Stellar post

Check out Episode 1: How a Hackathon Project Became a Web3 Startup 🚀

Ever wondered what it takes to build a web3 startup from scratch? In the Stellar Dev Diaries series, we follow the journey of a team of developers building on the Stellar Network as they go from hackathon win to getting funded and launching on mainnet.

Read more

Top comments (0)

PulumiUP 2025 image

PulumiUP 2025: Cloud Innovation Starts Here

Get inspired by experts at PulumiUP. Discover the latest in platform engineering, IaC, and DevOps. Keynote, demos, panel, and Q&A with Pulumi engineers.

Register Now

👋 Kindness is contagious

Engage with a wealth of insights in this thoughtful article, cherished by the supportive DEV Community. Coders of every background are encouraged to bring their perspectives and bolster our collective wisdom.

A sincere “thank you” often brightens someone’s day—share yours in the comments below!

On DEV, the act of sharing knowledge eases our journey and forges stronger community ties. Found value in this? A quick thank-you to the author can make a world of difference.

Okay