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

Next.js中如何在_app.tsx基于用户角色权限实现路由重定向

问题原因
  • ReferenceError: window is not defined 是因为Next.js默认会在服务端执行_app.tsx的渲染逻辑,服务端不存在window、localStorage等浏览器专属API,直接调用就会抛出该错误。
  • 直接在组件顶层调用跳转逻辑不符合React渲染规则,在服务端渲染阶段也无法执行路由跳转操作。
解决方案

将权限判断和跳转逻辑放到仅在客户端执行的useEffect钩子中,同时增加加载状态避免闪屏,示例代码如下:

import { useEffect, useState } from 'react';
import { useRouter } from 'next/router';

// 注意提前定义User类型
type User = {
  // 你的User字段定义
  role: string;
}

const App: React.FC<{
  Component: React.FC;
  pageProps: Record<string, any>;
}> = ({ Component, pageProps }) => {
  const router = useRouter();
  // 加载状态,避免跳转前闪显无权页面
  const [authLoading, setAuthLoading] = useState(true);
  const [isAllowed, setIsAllowed] = useState(false);

  useEffect(() => {
    // 仅客户端执行,不会触发服务端报错
    const user = JSON.parse(localStorage.getItem('user') ?? 'null') as User | null;
    const allowed = useRouteProvider(router.pathname, user?.role);
    setIsAllowed(allowed);

    if (!allowed) {
      // replace替代push,避免用户后退回到无权路径
      router.replace('/').finally(() => setAuthLoading(false));
      return;
    }
    setAuthLoading(false);
  }, [router.pathname]);

  if (authLoading) {
    // 可替换为你的项目全局Loading组件
    return <div>加载中...</div>;
  }

  if (!isAllowed) return null;

  return <Component {...pageProps} />;
};

export default App;
补充说明
  • 如果你的项目是Next.js 12+版本,更推荐使用Next.js中间件做全局权限拦截,逻辑更统一,也不会出现客户端闪屏问题。
  • 如果部分页面不需要权限校验,可以在useRouteProvider逻辑中增加路由白名单判断,避免误拦截。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 17:06:08