Next.js 에 Styled Component 끼얹기

박정훈·2022년 1월 10일
0

styled-component

목록 보기
2/2

React 와 다른 부분만 기록 해 둔다.
내 소개 사이트에 적용...
Next.js Docs
Next.js github

Custom app, document

Custom app
Custom document
app.tsx 와 document 파일을 custimizing 해 줘야 한다. (create next 로 만들어서 기존에 파일이 없었다. 파일을 추가 해 주고 커스터 마이징 해줬다.)
app 에서 style 을 뿌려주고, document 는 Next.js 와 styled-component 가 그려내는 방식이 달라서 custom 한다.
Next.js 는 서버에서 렌더링을 모두 마치지만(SSR) styled-component는 Client 단에서 그려내기 때문에 CSS가 입혀지기 전에 그려내 버린다. 따라서 document 에서 미리 CSS 를 적용 시킨다.

app.tsx

// pages/_app.tsx
import type { AppProps } from "next/app";
import { GlobalStyle } from "../styles/GlobalStyle";
import { ThemeProvider } from "styled-components";
import theme from "../styles/theme";
import CustomHead from "../components/CustomHead";

function MyApp({ Component, pageProps }: AppProps) {
  return (
    <>
      <ThemeProvider theme={theme}>
        <GlobalStyle />
        <CustomHead />
        <Component {...pageProps} />
      </ThemeProvider>
    </>
  );
}

export default MyApp;

document.tsx

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

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,
        styles: (
          <>
            {initialProps.styles}
            {sheet.getStyleElement()}
          </>
        ),
      };
    } finally {
      sheet.seal();
    }
  }
// Head 안의 link 처럼 meta tag 나 웹폰트를 추가 할 수 있다.
  render() {
    return (
      <Html>
        <Head>
          <link
            href="https://fonts.googleapis.com/css2?family=Roboto&display=swap"
            rel="stylesheet"
          />
        </Head>
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    );
  }
}

export default MyDocument;

.babelrc

npm install --save-dev babel-plugin-styled-components

styled-component babel plugin
최초 SSR 이후부터는 CSR로 라우팅을 한다. 해당 플러그인을 설치하지 않았다면, 서버에 발생했던 해시값과 브라우저에서 발생한 해시값이 서로 달라져서 에러를 뱉어낸다. 내가 그랬다...

{
  "presets": ["next/babel"],
  "plugins": ["babel-plugin-styled-components"]
}
profile
그냥 개인적으로 공부한 글들에 불과

0개의 댓글