You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js 13 App目录下nextjs-progressbar无法工作,求实现方法

在Next.js 13 App目录中实现进度条的正确方法

nextjs-progressbar是为Pages Router设计的,依赖旧的路由事件系统,在App Router中无法正常触发。下面提供两种可行的解决方案:

方案一:使用适配App Router的进度条包

推荐使用nextjs-toploader,它专门支持Next.js 13+的App Router:

  1. 安装依赖
npm install nextjs-toploader
# 或
yarn add nextjs-toploader
  1. 修改根layout组件
    将原代码中的NextNProgress替换为NextTopLoader,确保组件带有"use client"指令:
"use client";
import { ChakraProvider } from "@chakra-ui/react";
import "../styles/globals.css";
import NextTopLoader from "nextjs-toploader";
import { wrapper } from "../store";

function RootLayout({ children }) {
  return (
    <html>
      <head />
      <body className="max-w-7xl mx-auto">
        <ChakraProvider>
          <NextTopLoader color="#06373a" />
          {children}
        </ChakraProvider>
      </body>
    </html>
  );
}

export default wrapper.withRedux(RootLayout);

方案二:手动实现进度条

如果不想额外安装包,可以基于App Router的路由事件手动实现:

  1. 创建客户端组件ProgressBar.jsx
"use client";

import { useEffect, useState } from "react";
import { useRouter } from "next/navigation";

export default function ProgressBar() {
  const [progress, setProgress] = useState(0);
  const [isVisible, setIsVisible] = useState(false);
  const router = useRouter();

  useEffect(() => {
    const startProgress = () => {
      setIsVisible(true);
      setProgress(0);
      const timer = setInterval(() => {
        setProgress(prev => {
          if (prev >= 90) {
            clearInterval(timer);
            return prev;
          }
          return prev + 10;
        });
      }, 100);
    };

    const finishProgress = () => {
      setProgress(100);
      setTimeout(() => setIsVisible(false), 300);
    };

    router.events.on("routeChangeStart", startProgress);
    router.events.on("routeChangeComplete", finishProgress);
    router.events.on("routeChangeError", finishProgress);

    return () => {
      router.events.off("routeChangeStart", startProgress);
      router.events.off("routeChangeComplete", finishProgress);
      router.events.off("routeChangeError", finishProgress);
    };
  }, [router]);

  return isVisible ? (
    <div
      style={{
        position: "fixed",
        top: 0,
        left: 0,
        right: 0,
        height: "3px",
        backgroundColor: "#06373a",
        width: `${progress}%`,
        zIndex: 9999,
        transition: "width 0.2s ease-out",
      }}
    />
  ) : null;
}
  1. 在根layout中引入该组件
"use client";
import { ChakraProvider } from "@chakra-ui/react";
import "../styles/globals.css";
import ProgressBar from "./ProgressBar";
import { wrapper } from "../store";

function RootLayout({ children }) {
  return (
    <html>
      <head />
      <body className="max-w-7xl mx-auto">
        <ChakraProvider>
          <ProgressBar />
          {children}
        </ChakraProvider>
      </body>
    </html>
  );
}

export default wrapper.withRedux(RootLayout);

内容的提问来源于stack exchange,提问作者mobix

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 09:30:58