Show a progress bar while a React transition is in progress.
npm install react-transition-progress framer-motion
The main package react-transition-progress
exports three APIs: ProgressBarProvider
, ProgressBar
, and useProgress
.
ProgressBarProvider
provides the state and context forProgressBar
anduseProgress
ProgressBar
is the displayed progressbaruseProgress
is the way you start/finish the progressbar
There is also Next.js specific helper for next/link
in react-transition-progress/next
:
Link
is a wrapper fornext/link
that is instrumented to show theProgressBar
For example integrating into the Next.js App Router:
// app/layout.tsx
import { ProgressBar, ProgressBarProvider } from "react-transition-progress";
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en">
<body>
<ProgressBarProvider>
{/* I.e. using Tailwind CSS to show the progress bar with custom styling */}
<ProgressBar className="fixed h-1 shadow-lg shadow-sky-500/20 bg-sky-500 top-0" />
{children}
</ProgressBarProvider>
</body>
</html>
);
}
Using useProgress
to show the ProgressBar
when the React transition runs:
// components/my-component.tsx
"use client";
import { useState, startTransition } from "react";
import { useProgress } from "react-transition-progress";
export default function MyComponent() {
const startProgress = useProgress();
const [count, setCount] = useState(0);
return (
<>
<h1>Current count: {count}</h1>
<button
onClick={() => {
startTransition(async () => {
startProgress();
// Introduces artificial slowdown
await new Promise((resolve) => setTimeout(resolve, 2000));
setCount((count) => count + 1);
});
}}
>
Trigger transition
</button>
</>
);
}
You can also create nested progress bars by adding ProgressBarProvider
and ProgressBar
deeper in the React tree:
import MyComponent from "@/components/my-component";
import { ProgressBar, ProgressBarProvider } from "react-transition-progress";
import { Link } from "react-transition-progress/next";
export default function Home() {
return (
<>
<div className="m-10">
<ProgressBarProvider>
<h2 className="mb-2 pb-1 text-2xl font-semibold relative">
My Title
{/* I.e. using Tailwind CSS to show the progress bar with custom styling */}
<ProgressBar className="absolute h-1 shadow-lg shadow-sky-500/20 bg-sky-500 bottom-0" />
</h2>
<MyComponent />
</ProgressBarProvider>
</div>
</>
);
}
Using Next.js helper for Link
to show the progress bar for next/link
:
// app/page.tsx
import { Link } from "react-transition-progress/next";
export default function Home() {
return (
<div>
<h1>Home</h1>
<Link href="/about">Go to about page</Link>
</div>
);
}
See the Contributing Guide.
- Tim Neutkens (@timneutkens)
- Sam Selikoff (@samselikoff)
- Ryan Toronto (@ryantotweets)
This package is an improved version of the demo shown in Sam & Ryan's article on Build UI. It leverages React's useOptimistic
to track React Transitions.