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

Next.js项目添加Auth0Provider时window未定义的问题解决咨询

Next.js项目添加Auth0Provider时window未定义的问题解决咨询

嘿,我完全懂你碰到的这个问题!Next.js的服务端渲染(SSR)特性在这里给你挖了个小坑——服务端运行代码的时候根本没有浏览器里的window对象,所以你直接写window.location.origin就会报错啦。下面给你几个靠谱的解决办法:

方法一:用useEffect在客户端动态获取redirect_uri

useEffect钩子只会在客户端渲染阶段执行,这时候就能安全访问window了。我们可以用状态来存储redirect_uri,等客户端渲染完成后再赋值:

import { useEffect, useState } from 'react';
import { Auth0Provider } from '@auth0/auth0-react';
import Head from 'next/head';
// 记得导入你的其他组件和样式

export default function Home() {
  const [redirectUri, setRedirectUri] = useState('');
  const domain = process.env.NEXT_PUBLIC_AUTH0_DOMAIN;
  const clientId = process.env.NEXT_PUBLIC_AUTH0_CLIENT_ID;

  useEffect(() => {
    // 这段代码只会在浏览器环境里执行,放心访问window
    setRedirectUri(window.location.origin);
  }, []);

  // 确保redirectUri有值后再渲染Auth0Provider,避免初始加载的问题
  if (!redirectUri) {
    return <div>Loading...</div>;
  }

  return (
    <Auth0Provider 
      domain={domain} 
      clientId={clientId} 
      authorizationParams={{
        redirect_uri: redirectUri
      }}
    >
      <>
        <Head>
          <title>THEJackieGleason</title>
          <meta name="description" content="My Personal Website"/>
          <meta name="viewport" content="width=device-width, initial-scale=1"/>
          <link rel="icon" href="/favicon.ico"/>
        </Head>
        <Header/>
        <div className={`${styles.wrapper} z-10`}>
          <ThemeProvider theme={main}>
            <HomePage/>
            <Footer/>
          </ThemeProvider>
        </div>
      </>
    </Auth0Provider>
  );
}

方法二:把Auth0Provider封装成客户端专用组件

如果想把Auth0的逻辑和页面代码分开,可以把Auth0Provider封装成一个单独组件,然后用Next.js的动态导入功能,指定它只在客户端渲染:

第一步:创建Auth0Wrapper组件

// components/Auth0Wrapper.tsx
import { Auth0Provider } from '@auth0/auth0-react';

type Auth0WrapperProps = {
  children: React.ReactNode;
};

export default function Auth0Wrapper({ children }: Auth0WrapperProps) {
  const domain = process.env.NEXT_PUBLIC_AUTH0_DOMAIN;
  const clientId = process.env.NEXT_PUBLIC_AUTH0_CLIENT_ID;

  return (
    <Auth0Provider 
      domain={domain} 
      clientId={clientId} 
      authorizationParams={{
        redirect_uri: window.location.origin
      }}
    >
      {children}
    </Auth0Provider>
  );
}

第二步:在页面中动态导入这个组件

import dynamic from 'next/dynamic';
import Head from 'next/head';
// 导入你的其他组件和样式

// 动态导入,指定ssr: false,让组件只在客户端渲染
const Auth0Wrapper = dynamic(() => import('../components/Auth0Wrapper'), {
  ssr: false,
  loading: () => <div>Loading...</div>
});

export default function Home() {
  return (
    <Auth0Wrapper>
      <>
        <Head>
          <title>THEJackieGleason</title>
          <meta name="description" content="My Personal Website"/>
          <meta name="viewport" content="width=device-width, initial-scale=1"/>
          <link rel="icon" href="/favicon.ico"/>
        </Head>
        <Header/>
        <div className={`${styles.wrapper} z-10`}>
          <ThemeProvider theme={main}>
            <HomePage/>
            <Footer/>
          </ThemeProvider>
        </div>
      </>
    </Auth0Wrapper>
  );
}

为什么会出现这个问题?

简单来说,Next.js在构建和首次渲染时会在Node.js环境(服务端)执行你的页面组件代码,而window是浏览器特有的全局对象,服务端根本不存在这个东西,所以直接访问就会抛出ReferenceError。我们的解决思路都是让访问window的代码只在客户端环境下执行,避开服务端渲染的阶段。

备注:内容来源于stack exchange,提问作者Jackie

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.22 14:59:39