꿀팁

React, Next.js, TypeScript 프로젝트에서 Disqus 통합하기

무지개 빵 공장 2025. 2. 8. 02:18
반응형

디스커스

 

 무료로 내 홈페이지에 댓글 기능을 만들 수 있는 디스커스는 정말 좋은서비스 입니다만.... React, Next.js, TypeScript 프로젝트에서 Disqus를 통합할 때 가장 흔히 발생하는 문제 중 하나가 바로 hydration 에러다. hydration 에러는 서버에서 렌더링된 HTML과 클라이언트에서 실행되는 React의 가상 DOM이 일치하지 않을 때 발생하는데, 이를 해결하지 않으면 페이지가 깨지거나 예기치 않은 동작이 발생할 수 있다.

 

1. hydration 에러의 원인

Disqus는 기본적으로 클라이언트 사이드에서 동적으로 스크립트를 삽입하고, 이를 통해 댓글을 불러오는 방식이다. 그런데 Next.js와 같은 서버 사이드 렌더링(SSR) 환경에서 dangerouslySetInnerHTML을 사용하여 Disqus 코드를 삽입하면, 서버에서 생성된 HTML과 클라이언트에서 실행되는 HTML이 달라져 hydration 에러가 발생할 가능성이 높다.

2. 해결 방법

이 문제를 해결하기 위해 사용할 수 있는 몇 가지 방법을 소개한다.

(1) disqus-react 라이브러리 사용

Disqus를 React 컴포넌트로 쉽게 사용할 수 있도록 도와주는 disqus-react 라이브러리를 활용하면, hydration 에러를 방지할 수 있다.

import { DiscussionEmbed } from 'disqus-react';

const DisqusComments: React.FC = () => {
  return (
    <DiscussionEmbed
      shortname='your-disqus-shortname'
      config={{
        url: window.location.href,
        identifier: 'unique-page-identifier',
        title: 'Page Title',
      }}
    />
  );
};

이 방법은 가장 간단하면서도 효과적인 해결책이다. 하지만 만약 disqus-react가 예상대로 동작하지 않거나, 추가적인 커스터마이징이 필요하다면 다른 방법을 고려해야 한다.

(2) useEffect를 사용한 클라이언트 사이드 스크립트 로딩

Disqus 스크립트를 클라이언트 사이드에서만 동적으로 삽입하면, 서버와 클라이언트 간의 HTML 불일치를 방지할 수 있다.

import { useEffect } from 'react';

const DisqusComments: React.FC = () => {
  useEffect(() => {
    const script = document.createElement('script');
    script.src = 'https://your-shortname.disqus.com/embed.js';
    script.setAttribute('data-timestamp', Date.now().toString());
    document.body.appendChild(script);

    return () => {
      document.body.removeChild(script);
    };
  }, []);

  return <div id="disqus_thread"></div>;
};

이 방법을 사용하면 hydration 에러를 방지할 수 있지만, useEffect의 동작 특성상 초기 렌더링 시점에서는 Disqus가 보이지 않다가 이후에 로딩되는 문제가 있다.

(3) 클라이언트 사이드 렌더링 (CSR) 사용

Next.js에서는 dynamic 함수를 이용해 특정 컴포넌트를 클라이언트 사이드에서만 렌더링하도록 설정할 수 있다.

import dynamic from 'next/dynamic';

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

const Page: React.FC = () => {
  return (
    <div>
      <h1>Page Content</h1>
      <DisqusComments />
    </div>
  );
};

이 방법을 사용하면 Disqus 컴포넌트는 서버에서 렌더링되지 않고, 클라이언트에서만 로딩되므로 hydration 에러가 발생하지 않는다.

(4) suppressHydrationWarning 사용

<div suppressHydrationWarning={true}> 속성을 추가하면 특정 요소에서 hydration 경고를 억제할 수 있다.

<div suppressHydrationWarning={true}>
  <div id="disqus_thread"></div>
</div>

하지만 이 방법은 근본적인 문제를 해결하지 못하며, 단순히 경고를 숨기는 역할만 하기 때문에 가급적 다른 해결책을 먼저 고려하는 것이 좋다.

 

3. 결론

Disqus를 React, Next.js, TypeScript 환경에서 사용할 때 가장 추천하는 방법은 disqus-react 라이브러리를 사용하는 것이다. 만약 이 방법이 맞지 않는다면 useEffect를 활용한 동적 스크립트 로딩이나 Next.js의 dynamic을 사용한 클라이언트 사이드 렌더링을 고려하는 것이 좋다. suppressHydrationWarning은 최후의 수단으로만 활용해야 한다.

결론적으로, Disqus는 클라이언트 사이드에서만 동작하도록 처리해야 한다. 그렇지 않으면 Next.js의 SSR과 충돌하여 hydration 에러를 유발할 가능성이 높다. 위에서 소개한 해결책을 활용하면 Next.js 프로젝트에서도 안정적으로 Disqus를 사용할 수 있을 것이다.

반응형