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

Next.js中如何正确使用window.location.pathname?代码报错求助

如何在Next.js中获取window.location.pathname?

你遇到的报错是因为Next.js支持服务端渲染(SSR),在服务端执行代码时,浏览器的window对象并不存在——你直接在模块顶层声明isAdmin,会在服务端初始化阶段就执行这段代码,自然会找不到window而报错。

下面分两种路由方案给出解决办法:

方案一:Next.js 13+ App Router(客户端组件)

在App Router中,需要先标记组件为客户端组件(添加'use client'指令),然后将依赖window的逻辑放在useEffect钩子中(useEffect仅在客户端执行):

基础实现

'use client';
import { useEffect, useState } from 'react';

export default function AdminCheckComponent() {
  const [isAdmin, setIsAdmin] = useState(false);

  useEffect(() => {
    // 仅在客户端执行,此时window已存在
    setIsAdmin(window.location.pathname.startsWith("/adminpath"));
  }, []);

  return <div>{isAdmin ? "当前是管理员页面" : "当前是普通页面"}</div>;
}

可复用的自定义Hook

如果需要在多个组件中复用这个判断逻辑,可以封装成自定义Hook:

'use client';
import { useEffect, useState } from 'react';

export function useIsAdmin() {
  const [isAdmin, setIsAdmin] = useState(false);

  useEffect(() => {
    const checkAdminPath = () => {
      setIsAdmin(window.location.pathname.startsWith("/adminpath"));
    };

    // 初始检查路径
    checkAdminPath();
    // 监听浏览器前进/后退的路由变化,实时更新状态
    window.addEventListener('popstate', checkAdminPath);

    // 组件卸载时移除监听
    return () => window.removeEventListener('popstate', checkAdminPath);
  }, []);

  return isAdmin;
}

在组件中使用这个Hook:

'use client';
import { useIsAdmin } from './hooks';

export default function SomeComponent() {
  const isAdmin = useIsAdmin();
  return <div>{isAdmin ? "管理员专属内容" : "普通用户内容"}</div>;
}

方案二:Pages Router

在Pages Router中,除了用useEffect访问window,更推荐使用Next.js提供的useRouter钩子来获取路径,避免直接操作浏览器对象:

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

export default function SomePage() {
  const router = useRouter();
  const [isAdmin, setIsAdmin] = useState(false);

  useEffect(() => {
    setIsAdmin(router.pathname.startsWith("/adminpath"));
  }, [router.pathname]); // 路由变化时重新检查

  return <div>{isAdmin ? "管理员页面" : "普通页面"}</div>;
}

关键注意点

永远不要在组件外部的顶层作用域直接访问window——服务端渲染阶段会执行这部分代码,而服务端没有window对象,必然会报错。所有依赖浏览器环境的逻辑,都要放在客户端专属的执行时机(比如useEffect、客户端组件的渲染逻辑中)。

内容的提问来源于stack exchange,提问作者Mıktad Tahir Durak

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 02:25:15