Error occurred prerendering page "/notice/form". Read more: https://nextjs.org/docs/messages/prerender-error ReferenceError: navigator is not defined Error occurred prerendering page "/notice/form". Read more: https://nextjs.org/docs/messages/prerender-e

agnusdei·2024년 9월 24일
// SSR 문제 발생 시 동적 임포트 적용하도록 설정
import dynamic from 'next/dynamic';
const ToastEditor = dynamic(() => import('@admin/components/ui/editor/editor'), { ssr: false });

로컬에서는 잘 동작하지만 배포 환경에서 문제가 발생하는 경우, 이는 주로 서버 사이드 렌더링(SSR)과 관련된 문제일 가능성이 큽니다. 로컬 개발 환경에서는 클라이언트 사이드 렌더링(CSR)이 주로 사용되기 때문에 문제가 발생하지 않을 수 있습니다.

다음은 이 문제를 해결하기 위한 몇 가지 접근 방법입니다:

1. 클라이언트 전용 컴포넌트로 분리

Next.js에서 클라이언트 전용 컴포넌트를 사용하여 문제를 해결할 수 있습니다. ToastEditor 컴포넌트를 클라이언트 전용으로 설정하고, 서버 사이드 렌더링 중에는 해당 컴포넌트를 렌더링하지 않도록 할 수 있습니다.

'use client';

import '@toast-ui/editor/dist/i18n/ko-kr';
import '@toast-ui/editor/dist/toastui-editor.css';

import { Editor } from '@toast-ui/react-editor';
import { createRef, useEffect } from 'react';

export type CustomEditorProps = {
  id?: string;
  value?: string;
  onChange?: (value: { plain?: string; html?: string; markdown?: string }) => void;
};

const ToastEditor = ({ value, onChange, id }: CustomEditorProps) => {
  const ref = createRef<Editor>();

  const valueChange = () => {
    if (!ref.current) return;

    const instance = ref.current.getInstance();
    const plainText = instance.getMarkdown();
    const htmlContent = instance.getHTML();
    const markdownContent = instance.getMarkdown();

    onChange &&
      onChange({
        plain: plainText,
        html: htmlContent,
        markdown: markdownContent,
      });
  };

  useEffect(() => {
    if (id && ref.current) {
      ref.current.getInstance().setMarkdown(value || '');
    }
  }, [id, value]);

  return (
    <Editor
      placeholder="내용을 입력해주세요."
      ref={ref}
      language="ko-KR"
      viewer={false}
      initialValue={value || ' '}
      previewStyle="vertical"
      height="600px"
      initialEditType="markdown"
      onChange={valueChange}
    />
  );
};

export default ToastEditor;

2. 동적 임포트

Next.js의 dynamic 함수를 사용하여 클라이언트 전용 컴포넌트를 동적으로 임포트할 수 있습니다. 이렇게 하면 서버 사이드 렌더링 중에는 해당 컴포넌트가 렌더링되지 않습니다.

import dynamic from 'next/dynamic';

const ToastEditor = dynamic(() => import('../components/ToastEditor'), { ssr: false });

const YourPageComponent = () => {
  return (
    <div>
      <ToastEditor value="초기 값" onChange={(value) => console.log(value)} />
    </div>
  );
};

export default YourPageComponent;

3. 클라이언트 전용 코드 분리

클라이언트 전용 코드를 분리하여 서버 사이드 렌더링 중에는 실행되지 않도록 할 수 있습니다. 예를 들어, useEffect 훅을 사용하여 클라이언트에서만 실행되는 코드를 작성할 수 있습니다.

import { useEffect } from 'react';

const YourComponent = () => {
  useEffect(() => {
    if (typeof window !== 'undefined') {
      // 클라이언트에서만 실행되는 코드
    }
  }, []);

  return (
    <div>
      {/* 컴포넌트 내용 */}
    </div>
  );
};

export default YourComponent;

0개의 댓글