UNPKG

next-navigation-progress

Version:

A customizable navigation progress bar for Next.js apps with React 19 support

422 lines (305 loc) • 12.1 kB
# next-navigation-progress [![npm version](https://img.shields.io/npm/v/next-navigation-progress.svg)](https://www.npmjs.com/package/next-navigation-progress) [![npm downloads](https://img.shields.io/npm/dm/next-navigation-progress.svg)](https://www.npmjs.com/package/next-navigation-progress) [![Coverage Status](https://img.shields.io/codecov/c/github/thu-san/next-navigation-progress)](https://codecov.io/gh/thu-san/next-navigation-progress) [![Build Status](https://img.shields.io/github/actions/workflow/status/thu-san/next-navigation-progress/test.yml?branch=main)](https://github.com/thu-san/next-navigation-progress/actions) [![GitHub Release](https://img.shields.io/github/v/release/thu-san/next-navigation-progress)](https://github.com/thu-san/next-navigation-progress/releases) [![License](https://img.shields.io/npm/l/next-navigation-progress.svg)](https://github.com/thu-san/next-navigation-progress/blob/main/LICENSE) [![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue.svg)](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.