-
[Next.js13] Next.js13에서 Styled-components 적용 이슈front-end/Next.js 2023. 8. 5. 22:25
개요
Next.js 13에서 styled-components 을 적용해서 작업을 하고있었는데, 코드 수정을하고 새로고침할때마다 ,스타일이 적용이 안된
html이 나오고, 아래 gif 처럼시간이 조금 지나서야 styled-components 가 적용이 된걸 볼 수있습니다.

이를 수정하기 위해 Next.js 공식문서에 검색을 해봤습니다.
css-in-js (style-components) 관련하여 검색해보면 가장 첫째줄에,
경고: 런타임 JavaScript가 필요한 CSS-in-JS 라이브러리는 현재 서버 컴포넌트에서 지원되지 않습니다. CSS-in-JS를 서버 컴포넌트 및 스트리밍과 같은 최신 React 기능과 함께 사용하려면 라이브러리 제작자가 동시 렌더링을 포함한 최신 버전의 React를 지원해야 합니다. 우리는 React 팀과 협력하여 React Server Components 및 스트리밍 아키텍처를 지원하는 CSS 및 JavaScript 자산을 처리하기 위한 상류 API를 개발 중입니다.
지금 next.js 13은 컴포넌트가 default가 서버 컴포넌트인데요, style-component를 이용하려면 클라이언트 컴포넌트에서만 사용 가능 한것같습니다.
원인 및 해결방법
원인을 알아보기전에 , 우선 Next.js가 서버사이드 렌더링을 지원한다는 점입니다.
서버사이드 렌더링 후에 페이지를 렌더링하기 전에 스타일을 가져오지 않기 때문에 스타일이 올바르게 로드되지 않는 문제가 발생하는것입니다.해결방법은 먼저, app 경로에 registry.tsx 파일을 하나 생성 해줍니다.
styled-components API를 사용하여 렌더링 중에 생성된 모든 CSS 스타일 규칙을 수집하는 전역 레지스트리 컴포넌트를 생성하고, 이러한 규칙을 반환하는 함수를 만듭니다. 그런 다음 useServerInsertedHTML 훅을 사용하여 레지스트리에서 수집된 스타일을 루트 레이아웃의 <head> HTML 태그에 주입합니다.
//app/registry.tsx 'use client' import React, { useState } from 'react' import { useServerInsertedHTML } from 'next/navigation' import { ServerStyleSheet, StyleSheetManager } from 'styled-components' export default function StyledComponentsRegistry({ children, }: { children: React.ReactNode }) { // Only create stylesheet once with lazy initial state // x-ref: https://reactjs.org/docs/hooks-reference.html#lazy-initial-state const [styledComponentsStyleSheet] = useState(() => new ServerStyleSheet()) useServerInsertedHTML(() => { const styles = styledComponentsStyleSheet.getStyleElement() styledComponentsStyleSheet.instance.clearTag() return <>{styles}</> }) if (typeof window !== 'undefined') return <>{children}</> return ( <StyleSheetManager sheet={styledComponentsStyleSheet.instance}> {children} </StyleSheetManager> ) }layout.tsx 에서 래핑을 해줍니다.
// app/layout.tsx import StyledJsxRegistry from './registry' export default function RootLayout({ children, }: { children: React.ReactNode }) { return ( <html> <body> <StyledJsxRegistry>{children}</StyledJsxRegistry> </body> </html> ) }이렇게 세팅을 하면 서버사이드 렌더링 후에 페이지를 렌더링하기 전에 스타일을 가져올 수 있습니다.
그리고 Server Component가 아닌 'use client'를 이용하여 Client Component 에서 Style-component 를 이용해야합니다.
Reference
https://dev.to/rsanchezp/next-js-and-styled-components-style-loading-issue-3i68
Next.js and Styled-Components: style loading issue
Server-side render styles and fix the style loading issue.
dev.to
https://www.youtube.com/watch?v=3tgrPm2aKog
https://nextjs.org/docs/app/building-your-application/styling/css-in-js
Styling: CSS-in-JS | Next.js
Warning: CSS-in-JS libraries which require runtime JavaScript are not currently supported in Server Components. Using CSS-in-JS with newer React features like Server Components and Streaming requires library authors to support the latest version of React,
nextjs.org
'front-end > Next.js' 카테고리의 다른 글
[Next.js13] react-query로 SSR 및 Hydrate 구현 해보기 (0) 2023.08.05 Incremental Static Regenerate 렌더링 (feat: SSR,SSG,CSR) (0) 2023.07.27 [Next.js] Next.js의 Hydrate 이란? (feat: SSR , CSR) (0) 2023.07.24 [Next.js 13] OAuth SNS Login 구현 ( github, google, naver ) (0) 2023.07.18 [Next.js 13] 1. 토이프로젝트 하면서 공부한 내용 정리 (Prisma) (0) 2023.06.25