Notice
Recent Posts
Recent Comments
관리 메뉴

즐겁게, 코드

Next.js & styled-components - 렌더링 이전에 스타일 적용하기 본문

🎨 프론트엔드/Next.js

Next.js & styled-components - 렌더링 이전에 스타일 적용하기

Chamming2 2021. 5. 29. 00:00

바벨 파일 세팅과 _document.tsx만 저렇게 주어진 템플릿대로 구성하면 ServerStyleSheet 설정을 적용할 수 있는데요, 이러면 서버에서 문서를 내려받을 때 스타일이 적용된 문서를 내려받음으로써 렌더링 이전에 styled-components를 통한 스타일이 적용되지 않는 문제를 방지할 수 있습니다.

 

처음 보면 어려울 수도 있고, 템플릿이 외워서 칠만큼 간단하지도 않은 만큼 이번 기회에 블로그에 메모해두려 합니다.

1. 의존성 패키지 설치

npm i styled-components babel-plugin-styled-components
npm i -D @types/styled-components

2. .babelrc 파일을 루트 폴더에 생성한 후, 다음과 같이 작성한다.

{
  "presets": ["next/babel"],
  "plugins": [["styled-components", { "ssr": true }]]
}

3. _document.tsx를 다음과 같이 작성한다.

// pages/_document.tsx
// 기존 document 파일과 역할은 동일하나, 서버에서 styled-components를 적용한 문서를 내려주게 된다.

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

export default class MyDocument extends Document {
  static async getInitialProps(ctx: any) {
    const sheet = new ServerStyleSheet();
    const originalRenderPage = ctx.renderPage;

    try {
      ctx.renderPage = () =>
        originalRenderPage({
          enhanceApp: (App: any) => (props: any) => sheet.collectStyles(<App {...props} />),
        });

      const initialProps = await Document.getInitialProps(ctx);
      return {
        ...initialProps,
        styles: (
          <>
            {initialProps.styles}
            {sheet.getStyleElement()}
          </>
        ),
      };
    } finally {
      sheet.seal();
    }
  }

  // 여기부터는 문서 공통 정보를 다루는 기존 _document 파일의 역할과 동일합니다.
  render() {
    return (
      <Html>
        <Head>
          <body>
            <Main />
            <NextScript />
          </body>
        </Head>
      </Html>
    );
  }
}

 

🎯 적용 결과

좌 : ServerStyleSheet 적용 안했을때 / 우 : ServerStyleSheet 설정했을 때

이렇게 서버에서 문서를 내려받는 시점에 미리 styled-components를 통한 스타일을 적용할 수 있는 방법을 알아보았습니다. 😁

 

반응형
Comments
소소한 팁 : 광고를 눌러주시면, 제가 뮤지컬을 마음껏 보러다닐 수 있어요!
와!! 바로 눌러야겠네요! 😆