AgoraIO-Extensions / agora-rtc-react

Agora RTC React SDK
https://agoraio-extensions.github.io/agora-rtc-react/
MIT License
29 stars 10 forks source link

window is not defined error when integrating with nextjs #181

Closed yinjs closed 9 months ago

yinjs commented 9 months ago

What kind of problem do you need help?

"window is not defined" error when integrating with nextjs

Screenshot 2024-01-08 at 14 31 35

Sandbox to reproduce the issue https://codesandbox.io/p/devbox/agora-rtc-react-6x58n8

guoxianzhe commented 9 months ago

It seems you are running sdk in server side. you can use dynamically import like this:

useEffect(() => {
    const initSdk = async () => {
      const AgoraRTC = (await import("agora-rtc-react")).default;
      const client = AgoraRTC.createClient({ mode: "live", codec: "vp8" });
    };
    initSdk();
  }, []);
yinjs commented 9 months ago

@guoxianzhe Had tried your solution. Still get same error. Tried some other ways like const isBrowser = () => typeof window !== "undefined";. No luck. Lol... Sandbox updated with my latest tries.

guoxianzhe commented 9 months ago

@yinjs pls follow this Or you can create a component that has this import in the component and then use next/dynamic with ssr: false as you had tried

yinjs commented 9 months ago

@guoxianzhe thanks!

pasted my version in case someone need this.

// AgoraRTCProvider.tsx

"use client";
import { useState, useEffect, ReactNode, useRef } from "react";
import type { ClientConfig, IAgoraRTCClient } from "agora-rtc-react";
import dynamic from "next/dynamic";

const AgoraRTCProviderPrimitive = dynamic(
  () =>
    import("agora-rtc-react").then(({ AgoraRTCProvider }) => AgoraRTCProvider),
  {
    ssr: false,
  },
);

export default function AgoraRTCProvider(props: {
  clientConfig: ClientConfig;
  children: ReactNode;
}) {
  const clientConfigRef = useRef<ClientConfig>(props.clientConfig);
  const [client, setClient] = useState<IAgoraRTCClient>();

  useEffect(() => {
    const initSdk = async () => {
      const AgoraRTC = (await import("agora-rtc-react")).default;
      setClient(AgoraRTC.createClient(clientConfigRef.current));
    };
    initSdk();
  }, []);

  return (
    client && (
      <AgoraRTCProviderPrimitive client={client}>
        {props.children}
      </AgoraRTCProviderPrimitive>
    )
  );
}
Josh-Savvy commented 9 months ago
import { useState, useEffect, ReactNode, useRef } from "react";
import type { ClientConfig, IAgoraRTCClient } from "agora-rtc-react";
import dynamic from "next/dynamic";

const AgoraRTCProviderPrimitive = dynamic(
  () =>
    import("agora-rtc-react").then(({ AgoraRTCProvider }) => AgoraRTCProvider),
  {
    ssr: false,
  },
);

export default function AgoraRTCProvider(props: {
  clientConfig: ClientConfig;
  children: ReactNode;
}) {
  const clientConfigRef = useRef<ClientConfig>(props.clientConfig);
  const [client, setClient] = useState<IAgoraRTCClient>();

  useEffect(() => {
    const initSdk = async () => {
      const AgoraRTC = (await import("agora-rtc-react")).default;
      setClient(AgoraRTC.createClient(clientConfigRef.current));
    };
    initSdk();
  }, []);

  return (
    client && (
      <AgoraRTCProviderPrimitive client={client}>
        {props.children}
      </AgoraRTCProviderPrimitive>
    )
  );
}

Hi @yinjs, I'm having a similar issue, and this solution doesn't seem to be effective.

ERR: ReferenceError: window is not defined at new (/User......)

yinjs commented 9 months ago

@Josh-Savvy did you use impot ... from 'agora-rtc-react' some where before this Provider load?

Josh-Savvy commented 9 months ago

@Josh-Savvy did you use impot ... from 'agora-rtc-react' some where before this Provider load?

@yinjs Yeah, that was the issue, I forgot that I'd imported the AgoraRTCProvider directly in the layout.tsx before I found this solution. Thank you