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
- Calculate scroll position —
window.scrollYtells us how far down we've scrolled - Calculate total scrollable height — Total page height minus the viewport height
- Convert to percentage — Divide scroll position by total height
- 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.