Notice
Recent Posts
Recent Comments
Archives
반응형
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
Today
Total
09-20 11:33
250x250
관리 메뉴

꿈꾸는 개발자의 블로그

[Next.js] TypeScript + styled-components 사용하기 본문

Programming/Next.js

[Next.js] TypeScript + styled-components 사용하기

aldrn29 2022. 6. 15. 18:10

Next에서 styled-components를 사용하려면 초기 설정이 필요했다. _document 파일은 SSR시에 실행이 되는데, 여기에 스타일 설정을 해주면 서버에서 문서를 내려받을 때 스타일이 적용된 문서를 받을 수 있다. 만약 설정해놓지 않았다면,  styled-components를 통한 스타일이 적용되지 않고 랜더링 되는 문제가 생길 것이다! SSR 이후 내부 라우팅을 통해 페이지가 이동하면서 CSR을 하게 되는데, 이 때 서버에서 생성하는 해시값과 브라우저에서 생성하는 해시값이 달라서 에러가 발생한다. 이를 해결하기 위해서 바벨 플러그인을 설치해준다.

 


 

TypeScript + styled-components 사용하기

1. styled-components 설치

2. styled-components용 babel plugin, preset 설치

3. .babelrc 파일 생성

4. _document.tsx 파일 생성

 

1. styled-components 설치

$ yarn add styled-components @types/styled-components

 

2. styled-components용 babel plugin, preset 설치

$ yarn add babel-plugin-styled-components
//$ yarn add babel-preset-next

 

3. .babelrc 파일 생성

프로젝트 루트 경로에 파일을 생성한다. 그리고 아래 코드를 추가하여, 플러그인을 활성화시킨다.

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

 

4. _document.tsx 파일 생성

pages 폴더 하위에 파일을 생성하여 아래 코드를 추가한다.

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 lang="en">
                <Head>
                </Head>
                <body>
                    <Main />
                    <NextScript />
                </body>
            </Html>
        );
    }
}

export default MyDocument

 

참고 문서

 

728x90
728x90
Comments