본문 바로가기

study/Next.js

Next.js 13 - ReferenceError: window is not defined 오류

오류 메세지는 아래와 같다.

ReferenceError: window is not defined

api 모듈에서 window객체에 있는 함수를 사용하였는데 서버 컴포넌트에서는 당연히 사용할 수 없지만 클라이언트 컴포넌트에서도 오류가 발생하였다. 

 

문제 발생 원인

// window is not defined error
export const commonApi = {
  getUserOs() {
    const userOs = window.navigator.userAgent.replace(/ /g, '').toLowerCase();
    .....
    .....
    ~
    .....
    .....
  },
};

위의 getUserOs 함수를 클라이언트 컴포넌트에서 사용하였다.

export default function App() {
  // getUserOs 함수에서 오류 발생
  // window is not defined error
  const userOs = commonApi.getUserOs();
  return (<></>)
}

 

next.js에서 페이지를 처음 랜더링하는 과정에서는 window나 document전역객체가 존재하지 않아 발생하는 오류라고 한다. 나의 경우 navigator를 사용하기 위해 window에 접근하였는데 오류가 발생하였다. 

...

서버 컴포넌트에서 이 오류가 발생한다면 금방 이해 하겠다만... 'use client'를 선언한 클라이언트 컴포넌트에서 window객체 접근시에도 "next.js에서 페이지를 처음 랜더링하는 과정에서는 window나 document전역객체가 존재하지 않아 발생하는 오류라고 한다." 이 이유때문에 오류가 나타나는것 같다.

 

해결 방법

이를 해결하기 위해서는 useEffect Hook을 이용하면 된다.

useEffect Hook은 렌더링 이후에 호출되기 때문에 오직 클라이언트 사이드에서만 동작함을 보장할 수 있다고 한다.

export default function App() {
  const [userOs, setUserOs] = useState('');
  // useEffect Hook을 이용하여 랜더링 이후에 호출
  useEffect(() => {
    const getOs = commonApi.getUserOs();
    setUserOs(getOs);
  }, []);
  
  return (<></>)
}

위와같이 소스를 변경하여 문제를 해결하였다.