← λͺ©λ‘μœΌλ‘œ
Styled components with SSR

Reactμ—μ„œ μŠ€νƒ€μΌμ„ μž…νžˆλŠ” 방법은 μ—¬λŸ¬κ°€μ§€κ°€ μžˆμŠ΅λ‹ˆλ‹€. κ·Έ μ€‘μ—μ„œ CSS-in-JSλŠ” JavaScriptλ₯Ό μ‚¬μš©ν•˜μ—¬ μ»΄ν¬λ„ŒνŠΈμ˜ μŠ€νƒ€μΌμ„ μ •μ˜ν•˜λŠ” νŒ¨ν„΄μž…λ‹ˆλ‹€. styled-componentsλ‚˜ emotionκ³Ό 같은 λΌμ΄λΈŒλŸ¬λ¦¬λ“€μ΄ 이 νŒ¨ν„΄μ„ κ΅¬ν˜„ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€. μ΄λŸ¬ν•œ λΌμ΄λΈŒλŸ¬λ¦¬λ“€μ€ ν΄λΌμ΄μ–ΈνŠΈ μ‚¬μ΄λ“œ λ Œλ”λ§μ— μ΅œμ ν™”λ˜μ–΄ μžˆμ–΄, Next.js와 같은 SSR ν™˜κ²½μ—μ„œ μ‚¬μš©ν•˜κΈ° μœ„ν•΄μ„œλŠ” λͺ‡ κ°€μ§€ 좔가적인 섀정이 ν•„μš”ν•©λ‹ˆλ‹€.

μŠ€νƒ€μΌ μˆ˜μ§‘

μ„œλ²„ μ‚¬μ΄λ“œ λ Œλ”λ§ μ‹œ, 초기 HTML을 μƒμ„±ν•˜λŠ” μ‹œμ μ— λͺ¨λ“  styled-components의 μŠ€νƒ€μΌμ„ μˆ˜μ§‘ν•˜μ—¬ ν¬ν•¨μ‹œμΌœμ•Ό ν•©λ‹ˆλ‹€. 이λ₯Ό μœ„ν•΄ ServerStyleSheetλ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€:

μ—¬κΈ°μ„œ μ‚¬μš©λœ useServerInsertedHTML 훅은 Next.jsμ—μ„œ μ œκ³΅ν•˜λŠ” νŠΉλ³„ν•œ ν›…μœΌλ‘œ, SSR κ³Όμ •μ—μ„œ HTML을 μ£Όμž…ν•  수 있게 ν•΄μ€λ‹ˆλ‹€. 이λ₯Ό 톡해 μ„œλ²„μ—μ„œ μƒμ„±λœ μŠ€νƒ€μΌμ΄ 초기 HTML 응닡에 ν¬ν•¨λ©λ‹ˆλ‹€.

export const StyledComponentRegistry = ({ children }: PropsWithChildren) => {
  const [styleSheet] = useState(() => new ServerStyleSheet());

  useServerInsertedHTML(() => {
    const styles = styleSheet.getStyleElement();
    styleSheet.instance.clearTag();
    return <>{styles}</>;
  });

  if (typeof window !== 'undefined') return <>{children}</>;

  return <StyleSheetManager sheet={styleSheet.instance}>{children}</StyleSheetManager>;
};

export default function RootLayout({
  children,
}: Readonly<{
  children: ReactNode;
}>) {
  return (
    <html lang="en">
      <body>
        <StyledComponentRegistry>
          {children}
        </StyledComponentRegistry>
      </body>
    </html>
  );
}

클래슀 이름 일관성 보μž₯

CSS-in-JS λΌμ΄λΈŒλŸ¬λ¦¬λŠ” μŠ€νƒ€μΌλ§ˆλ‹€ κ³ μœ ν•œ ν•΄μ‹œκ°’μ„ 클래슀 μ΄λ¦„μœΌλ‘œ μ‚¬μš©ν•©λ‹ˆλ‹€. μ„œλ²„ μ‚¬μ΄λ“œ λ Œλ”λ§κ³Ό ν΄λΌμ΄μ–ΈνŠΈ μ‚¬μ΄λ“œ ν•˜μ΄λ“œλ ˆμ΄μ…˜ κ³Όμ •μ—μ„œ 이 클래슀 이름듀이 μΌμΉ˜ν•΄μ•Ό ν•˜λŠ”λ°, μ΄λŠ” λ‹€μŒκ³Ό 같은 λ°©μ‹μœΌλ‘œ ν•΄κ²°λ©λ‹ˆλ‹€:

  1. Next.js의 컴파일러 섀정을 톡해 λΉŒλ“œ μ‹œμ μ— 클래슀 이름을 μƒμ„±ν•©λ‹ˆλ‹€.
const nextConfig = {
  compiler: {
    styledComponents: {
      // 개발 ν™˜κ²½μ—μ„œ 디버깅을 μœ„ν•œ 클래슀λͺ… μ‚¬μš©
      displayName: process.env.NODE_ENV === 'development',
      // SSR 지원 ν™œμ„±ν™”
      ssr: true,
      // 더 μž‘μ€ λ²ˆλ“€ μ‚¬μ΄μ¦ˆλ₯Ό μœ„ν•œ μ„€μ •
      minify: true
    }
  }
};
  1. ServerStyleSheetκ°€ μ„œλ²„ μ‚¬μ΄λ“œμ—μ„œ μŠ€νƒ€μΌμ„ μˆ˜μ§‘ν•˜κ³ , 이λ₯Ό 초기 HTML에 ν¬ν•¨μ‹œν‚΅λ‹ˆλ‹€.
  2. ν΄λΌμ΄μ–ΈνŠΈ μ‚¬μ΄λ“œμ—μ„œλ„ λ™μΌν•œ ν•΄μ‹œ μ•Œκ³ λ¦¬μ¦˜μ„ μ‚¬μš©ν•˜μ—¬ 같은 클래슀 이름을 μƒμ„±ν•©λ‹ˆλ‹€.

μ΄λŸ¬ν•œ μ„€μ •κ³Ό λ©”μ»€λ‹ˆμ¦˜λ“€μ΄ ν•¨κ»˜ μž‘λ™ν•˜μ—¬ Styled-components λΌμ΄λΈŒλŸ¬λ¦¬κ°€ Next.js의 SSR ν™˜κ²½μ—μ„œ μ •μƒμ μœΌλ‘œ λ™μž‘ν•  수 있게 ν•©λ‹ˆλ‹€.