[next13] _document, styled-components

KoEunseo·2023년 7월 17일
0

next

목록 보기
3/4

그동안은 따로 뭔가 세팅하는 게 싫어서(귀찮아서) sass를 썼는데, 이번 프로젝트에서는 atomic design system을 제대로 써보고싶어서 styled components를 세팅해보았다.

next.js doc: styling css in js

lib/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>
  )
}

styled components로 생성된 모든 css를 수집하는 글로벌 레지스트리 컴포넌트 생성.

app/layout.tsx

그리고 useServerInsertedHTML 훅을 사용해서 루트 레이아웃의 html 태그에 넣어준다. 라는데 그냥 위에서 생성한 컴포넌트를 body 하위에서 children 감싸주는 형태로 넣으면 된다.

import "./globals.css";
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import StyledComponentsRegistry from "@/lib/registry";

const inter = Inter({ subsets: ["latin"] });

export const metadata: Metadata = {
  title: "Create Next App",
  description: "Generated by create next app",
};

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body className={inter.className}>
        <StyledComponentsRegistry>{children}</StyledComponentsRegistry>
      </body>
    </html>
  );
}
profile
주니어 플러터 개발자의 고군분투기

0개의 댓글