[Next.js] styled-component 적용하기
본문 바로가기
프레임워크/Next.js

[Next.js] styled-component 적용하기

by 은돌1113 2023. 1. 17.

Next.js에서 styled-component를 사용할 경우 생기는 문제

: Next.js는 SSR(Server Side Rendering)을 이용하여 페이지를 pre-rendering을 하기 때문에 클라이언트가 서버에 페이지 요청 시 HTML/CSS만 넘겨 받는다. / styled-component는 CSS-in-JS 형식으로써 JS로 작성된 스타일 요소들을 페이지에 주입 시킨다.

 

* pre-rendering이란?
: 서버에서 HTML 파일들을 미리 만들어 놓고 클라이언트에서 페이지 요청 시 서버에서 HTML 파일을 넘겨주는 방식

이는 퍼포먼스와 검색 SEO를 향상 시켜준다.

 

pre-render

사전에 HTML파일들을 만든다는의미이는 퍼포먼스와 검색SEO를 향상 시킬 수 있다 리액트로 만든 페이지는개발자 도구에서 JavaScript를 꺼보면 빈페이지로 나오는 곳이 많다서버사이드 렌더링으로

velog.io

 

그렇기 떄문에 Next.js에서 styled-component로 CSS를 작성하면 사용자가 페이지 진입 시 HTML/CSS를 먼저 그린 후에 JS가 그려지기 때문에 스타일이 뒤늦게 적용되는 문제가 발생한다.

 

Next.js에 styled-component 적용하기

 

[NextJS] styled-components와 함께 사용하기

시작하기 전에 NextJS는 기본적으로 페이지를 SSR을 이용해 pre-rendering한다. Server Side에서 html 파일을 구성하여 브라우저 측에 전달해 렌더링한다.(CSS도 렌더링됨) 이후 JS 파일이 로드되어 자바스크

velog.io

 

Next.js 고정 스타일링, styled-components 설치 및 사용법

1. CSS-in-JS 간단하게 말하자면 Javascript 코드에서 CSS를 작성하는 방식 2. CSS-in-JS 라이브러리 중, styled-components 설치 npm i styled-components - emotion 등등.. 2-1) styled-components용 babel 플러그인 및 preset 설치 n

record22.tistory.com

 

1. babel 설정하기

: Next.js는 페이지 접속 시 SSR(Server Side Rendering)을 이용하고 페이지 이동 시에는 CSR(Client Side Rendering)을 이용하여 페이지를 렌더링 한다.

 

이때 server와 client에서 생성하는 className에 해시값이 달라서 충돌이 발생한다.

* styled-component로 만들어진 컴포넌트는 내부적으로 태그의 className을 해시하여 만들어진다.

 

root 폴더 밑에 .babelrc 폴더를 생성하고 아래 코드를 삽입한다.

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

 

2. _document.js 설정하기

: pages 폴더 안에 _document.js 파일 생성하고 아래 코드를 삽입한다.

import Document from "next/document";
import Script from "next/script";

import { ServerStyleSheet } from "styled-components";

export default class MyDocument extends Document {

    static async getInitialProps(ctx) {
        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,
                styles: (
                    <>
                        {initialProps.styles}
                        {sheet.getStyleElement()}
                    </>
                ),
            };
        } finally {
            sheet.seal();
        }
    }
}

 

설정 끝!

댓글