next-navigation-progress
Version:
A customizable navigation progress bar for Next.js apps with React 19 support
422 lines (305 loc) ⢠12.1 kB
Markdown
# next-navigation-progress
[](https://www.npmjs.com/package/next-navigation-progress)
[](https://www.npmjs.com/package/next-navigation-progress)
[](https://codecov.io/gh/thu-san/next-navigation-progress)
[](https://github.com/thu-san/next-navigation-progress/actions)
[](https://github.com/thu-san/next-navigation-progress/releases)
[](https://github.com/thu-san/next-navigation-progress/blob/main/LICENSE)
[](https://www.typescriptlang.org/)
A lightweight, customizable navigation progress bar for Next.js applications with React 19 support. Shows a smooth progress indicator during route transitions using React's latest features like `useOptimistic` and `startTransition`.
## Demo
š **[View Live Demo](https://thu-san.github.io/next-navigation-progress/top)**
Experience the smooth navigation progress bar in action with our interactive demo showcasing various navigation patterns and customization options.
## Features
- š React 19 support with `useOptimistic` and `startTransition`
- šØ Fully customizable appearance
- š¦ Lightweight with zero dependencies (~2KB gzipped)
- š§ TypeScript support with full type definitions
- ā” Smooth animations with customizable easing functions
- šÆ Easy integration with Next.js App Router
- š Automatic progress management during route transitions
- š” Requires `'use client'` directive (uses React Context)
## Installation
```bash
npm install next-navigation-progress
# or
yarn add next-navigation-progress
# or
pnpm add next-navigation-progress
```
## Quick Start
> **Important**: This library uses React Context and hooks, so you must add the `'use client'` directive to any file that imports from `next-navigation-progress`.
### 1. Wrap your app with the provider
In your root layout or `_app.tsx`:
```tsx
'use client'; // Required! This library uses React Context
import { NextNavigationProgressProvider } from 'next-navigation-progress';
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body>
<NextNavigationProgressProvider>
{children}
</NextNavigationProgressProvider>
</body>
</html>
);
}
```
### 2. Add the progress bar component
Add the progress bar component inside the provider:
```tsx
'use client'; // Required! This library uses React Context
import {
NextNavigationProgressProvider,
NextNavigationProgressBar,
NavigationLink,
} from 'next-navigation-progress';
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body>
<NextNavigationProgressProvider>
<NextNavigationProgressBar />
{children}
</NextNavigationProgressProvider>
</body>
</html>
);
}
```
### 3. Trigger progress on navigation
You have two options for triggering the progress bar:
#### Option A: Using NavigationLink (Recommended)
The easiest way is to use the built-in `NavigationLink` component:
```tsx
'use client'; // Required! This library uses React Context
import { NavigationLink } from 'next-navigation-progress';
export default function MyComponent() {
return <NavigationLink href="/about">Go to About</NavigationLink>;
}
```
#### Option B: Using the hook manually
For more control, use the `useNavigationProgress` hook with `startTransition`:
```tsx
'use client'; // Required! This library uses React Context
import { useNavigationProgress } from 'next-navigation-progress';
import { useRouter } from 'next/navigation';
import { startTransition } from 'react';
export default function MyComponent() {
const router = useRouter();
const { startNewProgress } = useNavigationProgress();
const handleNavigation = (href: string) => {
startTransition(() => {
startNewProgress();
router.push(href);
});
};
return (
<button onClick={() => handleNavigation('/about')}>Go to About</button>
);
}
```
## TypeScript Examples
### Basic Usage with TypeScript
```tsx
'use client'; // Required! This library uses React Context
import type { FC, ReactNode } from 'react';
import {
NextNavigationProgressProvider,
NextNavigationProgressBar,
NavigationLink,
} from 'next-navigation-progress';
interface LayoutProps {
children: ReactNode;
}
const RootLayout: FC<LayoutProps> = ({ children }) => {
return (
<html lang="en">
<body>
<NextNavigationProgressProvider>
<NextNavigationProgressBar />
<nav>
<NavigationLink href="/" className="nav-link">
Home
</NavigationLink>
<NavigationLink href="/about" className="nav-link">
About
</NavigationLink>
</nav>
{children}
</NextNavigationProgressProvider>
</body>
</html>
);
};
export default RootLayout;
```
### Custom Hook with Type Safety
```tsx
'use client'; // Required! This library uses React Context
import { useNavigationProgress } from 'next-navigation-progress';
import { startTransition } from 'react';
import type { MouseEventHandler } from 'react';
function useCustomNavigation() {
const { progress, startNewProgress, optimisticObj, stateObj } =
useNavigationProgress();
const handleClick: MouseEventHandler<HTMLButtonElement> = (e) => {
e.preventDefault();
startTransition(() => {
startNewProgress();
// Your navigation logic here
});
};
return {
progress,
isLoading: optimisticObj.loading,
isShowing: stateObj.showing,
handleClick,
};
}
```
## API Reference
### Components
#### `NextNavigationProgressProvider`
The context provider that manages the progress state.
```tsx
<NextNavigationProgressProvider>{children}</NextNavigationProgressProvider>
```
#### `NextNavigationProgressBar`
The progress bar component that displays the navigation progress.
```tsx
<NextNavigationProgressBar />
```
Currently, the progress bar uses default styling with a blue color (#228be6) and 3px height. Custom styling can be achieved by creating your own progress component using the `useNavigationProgress` hook.
#### `NavigationLink`
A pre-configured Link component that automatically triggers the progress bar:
```tsx
<NavigationLink href="/about" className="link-class" prefetch={false}>
About Page
</NavigationLink>
```
**Props:**
| Prop | Type | Default | Description |
| ----------- | --------------------- | ------- | ------------------------- |
| `href` | `string` | - | The destination URL |
| `children` | `React.ReactNode` | - | Link content |
| `className` | `string` | - | CSS class name |
| `style` | `React.CSSProperties` | - | Inline styles |
| `target` | `string` | - | Link target attribute |
| `prefetch` | `boolean` | - | Next.js prefetch behavior |
| `onClick` | `function` | - | Click handler |
### Hooks
#### `useNavigationProgress()`
Returns the progress context with the following:
```tsx
const {
progress, // Current progress value (0-100)
startNewProgress, // Function to start new progress
optimisticObj, // { loading: boolean }
stateObj, // { showing: boolean }
} = useNavigationProgress();
```
## Advanced Usage
### Custom Progress Component
You can create your own progress component using the `useNavigationProgress` hook:
```tsx
'use client'; // Required! This library uses React Context
import { useNavigationProgress } from 'next-navigation-progress';
function CustomProgressBar() {
const { progress, stateObj } = useNavigationProgress();
if (!stateObj.showing) return null;
return (
<div className="custom-progress">
<div className="custom-progress-bar" style={{ width: `${progress}%` }} />
</div>
);
}
```
## Examples
Check out the [example](./example) directory for a complete Next.js application demonstrating various usage patterns and customizations.
To run the example:
```bash
cd example
npm install
npm run dev
```
## Troubleshooting
### Common Issues
#### Error: "useContext must be used within a Provider"
- **Solution**: Add `'use client'` directive at the top of your file. This library uses React Context which only works in client components.
```tsx
'use client'; // Add this line!
import { NextNavigationProgressProvider } from 'next-navigation-progress';
```
#### Progress bar not showing
- Ensure you've wrapped your app with `NextNavigationProgressProvider`
- Check that the file containing the provider has `'use client'` directive
- Verify you're using `NavigationLink` or calling `startNewProgress()` within `startTransition`
- Ensure you're using React 19 and Next.js 15 or later
#### TypeScript errors with React 19
- Make sure your `@types/react` and `@types/react-dom` are version 19+
- Update your `tsconfig.json` to include `"jsx": "react-jsx"`
#### Progress bar completes too quickly
- This is expected behavior for fast navigation. The progress animates to 90% gradually, then jumps to 100% when navigation completes
#### Custom styling not working
- The default progress bar uses inline styles. Create a custom component with `useNavigationProgress` hook for full styling control
## Browser Support
This library requires browsers that support React 19 features:
- Chrome/Edge 88+
- Firefox 78+
- Safari 14+
## Comparison with Similar Libraries
| Feature | next-navigation-progress | nextjs-toploader | nprogress |
| ------------------ | ------------------------ | ---------------- | --------- |
| React 19 Support | ā
| ā | ā |
| Zero Dependencies | ā
| ā | ā |
| TypeScript | ā
| ā
| ā |
| Bundle Size | ~2KB | ~4KB | ~7KB |
| Custom Animations | ā
| ā
| ā
|
| Next.js App Router | ā
| ā
| ā ļø |
## Testing
This package includes a comprehensive test suite using Vitest:
```bash
# Run tests
npm test
# Run tests in watch mode
npm run test
# Run tests once (for CI)
npm run test:run
# Generate coverage report
npm run test:coverage
# View interactive test UI
npm run test:ui
```
## Contributing
Contributions are welcome! Please feel free to submit a Pull Request. Make sure to:
1. Fork the repository
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
3. Write tests for new features
4. Ensure all tests pass
5. Commit your changes (`git commit -m 'Add some amazing feature'`)
6. Push to the branch (`git push origin feature/amazing-feature`)
7. Open a Pull Request
For more details, see [CONTRIBUTING.md](./CONTRIBUTING.md).
### Releasing
To release a new version:
```bash
npm run release # Interactive release process
npm run release:patch # Release a patch version (bug fixes)
npm run release:minor # Release a minor version (new features)
npm run release:major # Release a major version (breaking changes)
```
See [RELEASE_CHECKLIST.md](./RELEASE_CHECKLIST.md) for the complete release process.
## Changelog
See [CHANGELOG.md](./CHANGELOG.md) for a history of changes to this library.
## License
MIT - see [LICENSE](./LICENSE) for details.