Back to blog

Building a Reading Progress Bar in React

If you've been reading this blog, you might have noticed a blue bar at the top of the page that fills as you scroll. That's a reading progress bar — and it's surprisingly simple to build!

What It Does

The progress bar shows how far you've scrolled through an article:

  • 0% at the top
  • 100% at the bottom
  • Smoothly animates as you scroll

It gives readers a visual cue of how much content remains.

The Implementation

Here's the complete React component:

'use client';

import { useEffect, useState } from 'react';

export default function ReadingProgress() {
  const [progress, setProgress] = useState(0);

  useEffect(() => {
    const updateProgress = () => {
      const scrollTop = window.scrollY;
      const docHeight = document.documentElement.scrollHeight - window.innerHeight;
      const scrollPercent = docHeight > 0 ? (scrollTop / docHeight) * 100 : 0;
      setProgress(Math.min(100, Math.max(0, scrollPercent)));
    };

    window.addEventListener('scroll', updateProgress);
    updateProgress();

    return () => window.removeEventListener('scroll', updateProgress);
  }, []);

  return (
    <div className="fixed top-0 left-0 w-full h-1 bg-zinc-200 z-50">
      <div
        className="h-full bg-blue-500 transition-all duration-150"
        style={{ width: `${progress}%` }}
      />
    </div>
  );
}

How It Works

  1. Calculate scroll positionwindow.scrollY tells us how far down we've scrolled
  2. Calculate total scrollable height — Total page height minus the viewport height
  3. Convert to percentage — Divide scroll position by total height
  4. Clamp the value — Keep it between 0 and 100

The component listens to scroll events and updates the progress state, which drives the width of the blue bar.

Usage

Just add it to your page layout:

<>
  <ReadingProgress />
  <article>{/* Your content */}</article>
</>

That's it! Now scroll up and watch the progress bar shrink.

Share: