Logo
Search|
Published on

[Solved] "Window is Undefined" Error in Next.js

Authors
  • avatar
    Name
    Easyoon
    Twitter

Next.js에서 window is undefined 문제 해결하기

Next.js는 기본적으로 서버 사이드에서 렌더링을 수행하기 때문에(NodeJS),

브라우저 환경에만 존재하는 window 객체는 서버에서 접근할 수 없습니다.

이로 인해 window is not defined 오류가 발생할 수 있습니다.


1. window is undefined 오류가 발생하는 이유

Next.js는 서버 사이드 렌더링과 클라이언트 사이드 렌더링을 혼합하는 프레임워크입니다.

window 객체는 클라이언트(브라우저) 환경에서만 존재하므로, 서버에서는 존재하지 않습니다.

따라서 컴포넌트가 서버에서 렌더링될 때 window 객체를 사용하려고 하면 오류가 발생합니다.

By default, Next.js pre-renders every page. This means that Next.js generates HTML for each page in advance, instead of having it all done by client-side JavaScript. Pre-rendering can result in better performance and SEO.

NextJs 는 모든 페이지를 pre-render 시킵니다. 다시 말하자면 client-side 에서 Javascript 가 모든 것을 하는 대신에 HTML 페이지들을 사전에 만들어놓습니다. Pre-render 를 통해 더 좋은 퍼포먼스와 SEO 최적화를 만들어 낼 수 있습니다.

출처 : NextJs Document

Pre-rendering 에서 "window is not definded" 에러가 발생하게 됩니다.

React 는 Rendering 과정을 브라우저에게 모두 위임하기 때문에(client-side rendering)

브라우저의 window객체를 가지고 있지 않은 NextJs 의 경우, 모든 페이지를 Pre-rendering을 진행하려 하면 window is undefined 오류가 발생하게 됩니다.

즉, 웹 페이지가 만들어지는 시점이 server(NodeJs) 이고 nodejs 는 winddow 객체를 가지고 있지 않습니다.


2. 해결 방법

2.1 동적 임포트(dynamic)

Next.js는 클라이언트 전용으로 컴포넌트를 로드하기 위해 dynamic 함수를 제공합니다.

이 함수를 사용할 때 ssr: false 옵션을 설정하면 해당 컴포넌트를 서버 사이드에서 렌더링하지 않고 클라이언트에서만 로드합니다.

따라서, 해당 오류가 발생하는 곳을 찾아 동적 임포트를 해주면 됩니다.


import dynamic from 'next/dynamic';    

// 클라이언트 사이드에서만 로드되는 Calendar 컴포넌트
const Calendar = dynamic(() => import("@toast-ui/react-calendar"), { ssr: false });

이렇게 설정하면 Calendar 컴포넌트는 브라우저에서만 로드되기 때문에, window 객체를 사용하는 경우에도 문제가 발생하지 않습니다.

2.2 useEffect를 활용한 클라이언트 전용 코드 분리

useEffect 훅은 클라이언트에서만 실행되므로, window 객체를 참조하는 코드를 useEffect 안에 넣으면 서버 렌더링 단계에서는 실행되지 않습니다.

import { useEffect } from 'react';

const ExampleComponent = () => {
  useEffect(() => {
    // 이 코드는 클라이언트 사이드에서만 실행됩니다.
    console.log(window.innerWidth);
  }, []);

  return <div>윈도우 너비를 콘솔에 출력합니다.</div>;
};

이 방법을 사용하면 window를 참조하는 코드가 서버 사이드 렌더링 중에는 실행되지 않으므로 안전합니다.

2.3 typeof로 확인하기

typeof를 사용해서 window가 정의되어 있는지 확인하고, 브라우저 환경에서만 특정 코드를 실행할 수 있습니다.

if (typeof window !== "undefined") {
  // 이 코드는 브라우저에서만 실행됩니다.
  console.log("클라이언트 환경입니다.");
}

이 방법은 간단하게 특정 코드가 클라이언트에서만 실행되도록 할 때 유용합니다.


결론

Next.js에서 window is undefined 문제는 클라이언트 전용 코드가 서버 렌더링 중에도 실행될 때 발생합니다.

이를 해결하기 위해 dynamic 함수를 사용해 클라이언트 전용 컴포넌트를 동적으로 로드하거나,

useEffect 훅을 통해 브라우저 환경에서만 코드를 실행하거나,

typeof window !== "undefined"로 확인할 수 있습니다.