본문 바로가기
Next

Next.js - Styled-components 적용전 렌더링 되는 이슈

by 새발개발JA 2023. 4. 16.
반응형

 

 

 

 

요즘 한창 Next.js 프로젝트를 만드는 중이다.

Styled-components 가 첫 렌더에만 적용이 되고 새로고침을 한 후에는 적용이 안되는 이슈가 있었다.

열심히 구글링을 해본 결과, Next.js가 SSR로 동작하기 때문에 style 적용되기 전에 렌더링이 되어서 이슈가 발생한 것을 알게 되었다.

그렇기 때문에 서버로 요청이 들어오면 가장 먼저 실행하게 만들어야 한다.

해결책을 찾던 새발자는 _app.tsx_document.tsx 라는 서버 파일의 존재를 알게 되는데... 

 

 

 


Next.js - Styled-components 적용전 렌더링 되는 이슈

 

우리는 빨간 박스에 있는 부분에서 밑작업을 할 것이다. 위치를 잘 알아 놓자.

 

 

1. 일단 pages 폴더 안에 _app.tsx 를 _documnet.tsx 를 추가해주자

 

_app.tsx

  • app.tsx, _document.tsx: 두 파일은 server only file 이다
  • Next.js server logic에 사용되는 파일이다 (client 로직 사용 불가)
  • 서버로 요청이 들어왔을 때 가장 먼저 실행된다.
  • 레이아웃 설정을 통해 페이지 전환시 특정 레이아웃을 유지할 수 있다
import type { AppProps } from "next/app";
import Head from "next/head";

function MyApp({ Component, pageProps }: AppProps) {
  return (
    <>
      <Head>
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <title>테스트 타이틀</title>
      </Head>

      <Component {...pageProps} />
    </>
  );
}

export default MyApp;

 

_document.tsx

  • HTML 문서 내 공통 태그들을 커스터마이징 - head / mete 정보 / 폰트 / 웹 접근성 설정 / body 등
  • _app.tsx 다음으로 서버에서 실행된다. (클라이언트 로직 등은 실행 X - 브라우저 API / 이벤트 핸들러 등)
  • <Main /> 를 제외한 나머지는 브라우저에서 실행 X (서버에서 사용할 로직만 넣자)
  • _app.tsx가 실행되면서 갖추어진 content들은  <Main /> 하위로 생성
import Document, {
  Html,
  Head,
  Main,
  NextScript,
  DocumentContext,
} from "next/document";
import { ServerStyleSheet } from "styled-components";

class MyDocument extends Document {
  static async getInitialProps(ctx: DocumentContext) {
    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();
    }
  }

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

export default MyDocument;

 

 

2. 나머지 세팅 해주기 

 

설치 먼저 하고

npm i babel-plugin-styled-components -D

 

프로젝트 루트에서 babelrc 파일 만들고 아래 내용 추가해주기

vi ./~babelrc // 터미널에 명령어 치고들어가면 빈 파일이 만들어진다

 

아래 세팅 추가하고 :)

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

 

 

저장하고 나오기

:wq // 저장 후 닫기

 

 

 

 

 

 

ref:

 

https://velog.io/@woodong/2.-app.tsx-%EC%99%80-document.tsx

 

 

 

 

 

 

반응형

댓글