skip to Main Content

I have created a custom hook in Next JS to get network online status using JS navigator.onLine property. The code ran fine locally. However, when I ran npm run build to build the project, it threw me the following error saying that navigator is not defined. I can understand that this issue is related to hydration and pre-rendering but I am unable to fix it using all the possible solutions in my knowledge.

Below is my custom hook code:

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

const useNetworkStatus = () => {
  const [isOnline, setOnline] = useState<boolean>(true);

  const updateNetworkStatus = () => {
    if (typeof navigator !== 'undefined') {
      setOnline(navigator.onLine);
    }
  };

  //   sometimes, the load event does not trigger on some browsers, that is why manually calling updateNetworkStatus on initial mount
  useEffect(() => {
    updateNetworkStatus();
  }, []);

  useEffect(() => {
    window.addEventListener("load", updateNetworkStatus);
    window.addEventListener("online", updateNetworkStatus);
    window.addEventListener("offline", updateNetworkStatus);

    return () => {
      window.removeEventListener("load", updateNetworkStatus);
      window.removeEventListener("online", updateNetworkStatus);
      window.removeEventListener("offline", updateNetworkStatus);
    };
  }, [navigator.onLine]);

  return { isOnline };
};

export default useNetworkStatus;

I have been getting the navigator is not defined in all 7 files in which I have used my custom hook useNetWorkStatus. Following is the screenshot of the error:

enter image description here

2

Answers


  1. If you have added the event listeners in the useEffect, then you don’t need to pass the navigatior.onLine in the dependency array of the useEffect. It will check for the online and offline automatically.

    Reason you are getting error is navigator attached to the window object and it’s available on the client side only but Next will render the on the server despite of having the use client decorator.

    Login or Signup to reply.
  2. Inside you useEffect you are using window object. Since the window object is a part of Browser API and does not exist on the server, you encounter this error when your code tries to access it during SSR. This is typically handled by guarding such code with checks like if (typeof window !== "undefined")

    I have modified your code, try running the build after this modification.

    "use client";
    import { useEffect, useState } from "react";
    
    const useNetworkStatus = () => {
      const [isOnline, setOnline] = useState<boolean>(true);
    
      const updateNetworkStatus = () => {
        if (typeof navigator !== 'undefined') {
          setOnline(navigator.onLine);
        }
      };
    
      //   sometimes, the load event does not trigger on some browsers, that is why manually calling updateNetworkStatus on initial mount
      useEffect(() => {
        updateNetworkStatus();
      }, []);
    
      useEffect(() => {
        if (typeof window !== "undefined") {
          window.addEventListener("load", updateNetworkStatus);
          window.addEventListener("online", updateNetworkStatus);
          window.addEventListener("offline", updateNetworkStatus);
      
          return () => {
            window.removeEventListener("load", updateNetworkStatus);
            window.removeEventListener("online", updateNetworkStatus);
            window.removeEventListener("offline", updateNetworkStatus);
          };
        }
      }, [navigator.onLine]);
    
      return { isOnline };
    };
    
    export default useNetworkStatus;
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search