<개발>/<여개지>

next.js 에서 styled-components 가 제대로 안먹힐때

gosoeungduk 2022. 6. 24. 05:55
반응형

styled-componets 와 next.js 을 사용하여 개발하다보면 PropclassNamedid not match 라는 오류를 본 사람이 있을 것이다.

오류가 발생함과 동시에 페이지의 CSS 가 다 풀려버리는 경우가 생기는데, 서버사이드로 렌더링되는 next.js 쪽 파일과 클라이언트 사이드에서 렌더링 되는 styled-components 의 css 의 className 이 불일치해서 생기는(?) 문제라고 한다.

이를 일관성 있게 만들어주려면, _document.tsx 를 만들어주어야하고 babel-plugin-styled-components 을 사용하여야한다.

yarn add -dev babel-plugin-styled-components

일단 설치해주고, 바벨 옵션이 적용되도록 루트 디렉토리에 .babelrc 파일을 생성한다.

// .bablerc 파일
{
  "presets": ["next/babel"],
  "plugins": [
    [
      "babel-plugin-styled-components", 
      {
        "ssr": true, 
        "displayName": true,
        "pure": true 
      }
    ]
  ]
}

바벨 설정은 끝났고 다음은 _document.tsx 생성이다. 이건 pages 에 만들어주면 된다.

import Document, { Html, Head, Main, NextScript } from "next/document";
import { ServerStyleSheet } from "styled-components";
import { DocumentContext, DocumentInitialProps } from "next/document";

class MyDocument extends Document {
  static async getInitialProps(
    ctx: DocumentContext
  ): Promise<DocumentInitialProps> {
    const sheet = new ServerStyleSheet();
    const originalRenderPage = ctx.renderPage;
    try {
      ctx.renderPage = () =>
        originalRenderPage({
          enhanceApp: (App) => (props) =>
            sheet.collectStyles(<App {...props} />),
        });

      const initialProps = await Document.getInitialProps(ctx);
      return {
        ...initialProps,
      };
    } finally {
      sheet.seal();
    }
  }

  render() {
    return (
      <Html>
        <Head />
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    );
  }
}

export default MyDocument;

여기까지 하면 아마 css 가 풀리지않고 렌더링이 잘 될 것이다.

참고

_document.tsx 작성법

반응형