Next.js(App)에서 Chakra UI 사용하기
Next.js(App)에서 Chakra UI 사용하기 (Using Chakra UI in Next.js App)
Next.js app 디렉터리에 Chakra UI를 설치하는 방법을 안내하는 가이드예요. Next.js 15와 16에서 동작합니다. 스니펫과 원시 컴포넌트를 사용해 더 빠르게 UI를 구축할 수 있습니다.
출처: 문서
본문
호환성 (Compatibility)
Chakra UI는 Next.js 15와 16에서 동작해요.
Chakra UI는 특정 Next.js 메이저 버전에 묶여 있지 않아요. 프로젝트가 지원되는 React와 Emotion 버전을 사용한다면 이 가이드가 적용됩니다.
이 리포지토리의 템플릿은 안정성을 위해 이전 Next.js 메이저를 고정할 수도 있어요. 앱에서 next를 최신 메이저로 업그레이드할 수 있습니다.
템플릿 (Templates)
빠르게 시작하려면 다음 템플릿 중 하나를 사용하세요. 템플릿은 Chakra UI를 사용하도록 올바르게 구성되어 있어요.
- Next.js app 템플릿 (https://github.com/chakra-ui/chakra-ui/tree/main/sandbox/next-app)
- Next.js app (streaming) (https://github.com/chakra-ui/chakra-ui/tree/main/sandbox/next-app-streaming)
- Next.js pages 템플릿 (https://github.com/chakra-ui/chakra-ui/tree/main/sandbox/next-pages)
설치 (Installation)
최소 Node 버전은 Node.20.x입니다.
의존성 설치 (Install dependencies)
npm i @chakra-ui/react @emotion/react
스니펫 추가 (Add snippets)
스니펫은 UI를 더 빨리 구축하는 데 사용할 수 있는 사전 빌드된 컴포넌트예요. @chakra-ui/cli를 사용해 스니펫을 프로젝트에 추가할 수 있습니다.
npx @chakra-ui/cli snippet add
tsconfig 업데이트 (Update tsconfig)
TypeScript를 사용한다면 tsconfig 파일의 compilerOptions에 다음 옵션을 포함하도록 업데이트해야 해요.
{
"compilerOptions": {
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "Bundler",
"skipLibCheck": true,
"paths": {
"@/*": ["./src/*"]
}
}
}
JavaScript를 사용한다면
jsconfig.json파일을 만들고 위 코드를 파일에 추가하세요.
provider 설정 (Setup provider)
애플리케이션 루트에서 components/ui/provider 컴포넌트에 생성된 Provider 컴포넌트로 애플리케이션을 감싸세요.
이 provider는 다음을 조합해요.
- 스타일링 시스템을 위한
@chakra-ui/react의ChakraProvider - 컬러 모드를 위한
next-themes의ThemeProvider
import { Provider } from "@/components/ui/provider"
export default function RootLayout(props: { children: React.ReactNode }) {
const { children } = props
return (
<html suppressHydrationWarning>
<body>
<Provider>{children}</Provider>
</body>
</html>
)
}
html요소에suppressHydrationWarningprop을 추가하는 것은next-themes라이브러리에 대한 경고를 방지하기 위해 필요해요.
번들 최적화 (Optimize Bundle)
실제로 사용하는 모듈만 로드해 번들 크기를 최적화하려면 Next.js의 experimental.optimizePackageImports 기능을 사용하는 것을 권장해요.
export default {
experimental: {
optimizePackageImports: ["@chakra-ui/react"],
},
}
이것은 다음과 같은 경고를 해결하는 데도 도움이 됩니다.
[webpack.cache.PackFileCacheStrategy] Serializing big strings (xxxkiB)
Suspense를 통한 스트리밍 (Stream through Suspense, 선택)
<Suspense>를 통해 UI를 스트리밍하지 않는다면 이 부분은 건너뛰어도 돼요.
Chakra 컴포넌트가 스트리밍된 <Suspense> 청크 안에서 처음 나타날 때 필요합니다. Next.js 16에서 Cache Components를 활성화했다면 그것이 기본입니다.
@emotion/cache를 설치하고 이 레지스트리를 추가하세요.
"use client"
import createCache from "@emotion/cache"
import { CacheProvider } from "@emotion/react"
import { useServerInsertedHTML } from "next/navigation"
import { useState } from "react"
export function EmotionRegistry({ children }: { children: React.ReactNode }) {
const [{ cache, flush }] = useState(() => {
const cache = createCache({ key: "css" })
cache.compat = true
const previousInsert = cache.insert
let inserted: string[] = []
cache.insert = (...args) => {
const serialized = args[1]
if (cache.inserted[serialized.name] === undefined) {
inserted.push(serialized.name)
}
return previousInsert(...args)
}
const flush = () => {
const previouslyInserted = inserted
inserted = []
return previouslyInserted
}
return { cache, flush }
})
useServerInsertedHTML(() => {
const names = flush()
if (names.length === 0) return null
const styles = names.map((name) => cache.inserted[name]).join("")
return (
<style
data-emotion={`${cache.key} ${names.join(" ")}`}
dangerouslySetInnerHTML={{ __html: styles }}
/>
)
})
return <CacheProvider value={cache}>{children}</CacheProvider>
}
그다음 Provider를 그것으로 감싸세요.
import { EmotionRegistry } from "@/components/ui/emotion-registry"
import { Provider } from "@/components/ui/provider"
export default function RootLayout(props: { children: React.ReactNode }) {
return (
<html suppressHydrationWarning>
<body>
<EmotionRegistry>
<Provider>{props.children}</Provider>
</EmotionRegistry>
</body>
</html>
)
}
스트리밍 샌드박스는 위 레이아웃의 복사본이 아니라, 그대로 실행해 볼 수 있는 재현 프로젝트예요.
하이드레이션 오류 (Hydration errors, Turbopack)
오류가 다음과 같이 보인다면:
+<div className="chakra-xxx">
-<style data-emotion="css-global xxx" data-s="">
Turbopack이 Emotion CSS를 잘못 하이드레이션하고 있는 거예요. dev와 build 스크립트에 --webpack을 추가하세요.
- "dev": "next dev"
- "build": "next build"
+ "dev": "next dev --webpack"
+ "build": "next build --webpack"
Next.js 팀이 이 문제를 수정하면 이 가이드를 업데이트할게요.
즐거운 개발 되세요! (Enjoy!)
Chakra UI의 스니펫과 원시 컴포넌트의 힘으로 더 빠르게 UI를 구축할 수 있어요.
import { Button, HStack } from "@chakra-ui/react"
const Demo = () => {
return (
<HStack>
<Button>Click me</Button>
<Button>Click me</Button>
</HStack>
)
}