
chakra-ui-migrate
熱門將 Chakra UI 專案從 v2 遷移到 v3,涵蓋套件變更、codemod、Provider 設定、色彩模式、屬性重新命名、複合元件、主題、recipes 以及 Next.js 更新。當使用者升級 Chakra UI 版本、升級後遇到破壞性變更、轉換舊的 v2 模式(ColorModeScript、useColorModeValue、styleConfig、extendTheme、isDisabled、colorScheme、@chakra-ui/icons、framer-motion 依賴)、修正複合元件模式,或詢問 Chakra UI v2 與 v3 之間的差異時,請使用此技能——即使他們沒有明確說出「遷移」或「升級」。
將 Chakra UI 專案從 v2 遷移到 v3,涵蓋套件變更、codemod、Provider 設定、色彩模式、屬性重新命名、複合元件、主題、recipes 以及 Next.js 更新。當使用者升級 Chakra UI 版本、升級後遇到破壞性變更、轉換舊的 v2 模式(ColorModeScript、useColorModeValue、styleConfig、extendTheme、isDisabled、colorScheme、@chakra-ui/icons、framer-motion 依賴)、修正複合元件模式,或詢問 Chakra UI v2 與 v3 之間的差異時,請使用此技能——即使他們沒有明確說出「遷移」或「升級」。
Chakra UI 遷移:v2 → v3
您正在引導開發者將專案從 Chakra UI v2 遷移到 v3。請依序執行下列步驟。先檢查專案——切勿猜測套件版本或框架。
Node 需求: Chakra UI v3 需要 Node >= 20.x。若環境不確定,請先確認。
步驟 1 — 檢查專案
讀取這些檔案以了解目前狀態:
package.json
尋找:
- 目前的
@chakra-ui/react版本(v2.x 或 v3.x) - 相關套件:
@chakra-ui/icons、@chakra-ui/hooks、@chakra-ui/next-js、@emotion/styled、framer-motion - 框架:Next.js(App Router 或 Pages Router)、Vite、純 React
- 套件管理器(從鎖定檔:
pnpm-lock.yaml、yarn.lock、bun.lock、package-lock.json)
必要時抽查關鍵檔案:
- Provider / 主題設定(
_app.tsx、layout.tsx、theme.ts) - 色彩模式使用(
ColorModeScript、useColorMode、useColorModeValue) - 任何顯示大量 v2 模式的元件檔案
步驟 2 — 更新套件
移除僅限 v2 的依賴
# npm
npm uninstall @chakra-ui/icons @chakra-ui/hooks @chakra-ui/next-js @emotion/styled framer-motion
# pnpm
pnpm remove @chakra-ui/icons @chakra-ui/hooks @chakra-ui/next-js @emotion/styled framer-motion
# yarn
yarn remove @chakra-ui/icons @chakra-ui/hooks @chakra-ui/next-js @emotion/styled framer-motion
@emotion/styled 和 framer-motion 在 v3 中不再需要。
安裝 v3 核心套件
# npm
npm install @chakra-ui/react @emotion/react
# pnpm
pnpm add @chakra-ui/react @emotion/react
# yarn
yarn add @chakra-ui/react @emotion/react
已移除套件的替代方案
| 已移除 | 替代方案 |
|---|---|
@chakra-ui/icons |
lucide-react 或 react-icons |
@chakra-ui/hooks |
react-use 或 usehooks-ts |
@chakra-ui/next-js |
asChild 屬性模式(請參閱 Next.js 章節) |
步驟 3 — 執行 codemod
官方 codemod 會處理大部分機械性變更:元件重新命名、屬性更新、匯入重寫,以及複合元件重構。它無法取代人工審查——請務必審核輸出結果。
先進行乾執行(不會變更任何檔案):
npx @chakra-ui/codemod upgrade --dry
檢視它建議的內容。滿意後:
npx @chakra-ui/codemod upgrade
執行 codemod 後,先提交變更再進行手動編輯,這樣您就有乾淨的 diff 可以處理。
步驟 4 — 更新 Provider
舊的 v2 模式
// v2
import { ChakraProvider } from "@chakra-ui/react"
import theme from "./theme"
;<ChakraProvider theme={theme}>{children}</ChakraProvider>
新的 v3 模式(使用 Chakra CLI 片段)
產生 provider 和元件片段:
npx @chakra-ui/cli snippet add
這會建立 components/ui/provider.tsx(以及 toaster 和 tooltip 片段),並自動安裝所需的 npm 依賴——包括 next-themes。匯入並使用它:
// v3 — app/layout.tsx (Next.js App Router)
import { Provider } from "@/components/ui/provider"
;<html lang="en" suppressHydrationWarning>
<body>
<Provider>{children}</Provider>
</body>
</html>
Provider 檔案包含 "use client"——請勿在 layout.tsx 中加入。請參閱 Next.js 章節了解 Pages Router 的放置位置。
v3 中的自訂主題
將 extendTheme 替換為 createSystem:
// v2
import { extendTheme } from "@chakra-ui/react"
// v3
import { createSystem, defaultConfig, defineConfig } from "@chakra-ui/react"
export const theme = extendTheme({ colors: { brand: { 500: "#2196f3" } } })
const config = defineConfig({
theme: { tokens: { colors: { brand: { 500: { value: "#2196f3" } } } } },
})
export const system = createSystem(defaultConfig, config)
透過 value={system} 將 system 傳遞給 ChakraProvider。
步驟 5 — 色彩模式遷移
移除所有 v2 色彩模式模式
// 移除這些 v2 匯入和使用:
import { ColorModeScript } from "@chakra-ui/react"
// ❌
import { useColorMode } from "@chakra-ui/react"
// ❌ (改用 next-themes)
import { useColorModeValue } from "@chakra-ui/react"
// ❌ (改用 CSS tokens)
import { DarkMode, LightMode } from "@chakra-ui/react"
// ❌
// 同時從 _document.tsx 移除:
;<ColorModeScript initialColorMode={theme.config.initialColorMode} /> // ❌
v3 色彩模式方法
色彩模式由 next-themes 透過產生的 Provider 處理。使用會自動回應目前色彩模式的語意 tokens:
// 使用 Chakra 語意 tokens——它們會在暗色模式中自動切換
<Box color="fg.default" bg="bg.subtle">
...
</Box>
若要建立色彩模式切換器,請使用產生的 components/ui/color-mode.tsx 片段,或直接使用 next-themes 的 useColorMode。
步驟 6 — 屬性重新命名
這些布林和樣式屬性在 v3 中已重新命名,以與 HTML 和現代 React 慣例保持一致。codemod 會捕捉大部分這些變更,但之後請手動驗證。
布林屬性
| v2 | v3 |
|---|---|
isOpen |
open |
defaultIsOpen |
defaultOpen |
isDisabled |
disabled |
isInvalid |
invalid |
isRequired |
required |
isReadOnly |
readOnly |
isChecked |
checked |
isLoaded |
loaded |
isIndeterminate |
indeterminate |
樣式和版面屬性
| v2 | v3 |
|---|---|
colorScheme |
colorPalette |
noOfLines |
lineClamp |
truncated |
truncate |
spacing (Stack) |
gap |
apply |
textStyle 或 layerStyle |
巢狀樣式屬性
// v2 — 使用巢狀偽選擇器的 sx
<Box sx={{ "&:hover": { color: "blue.500" } }} />
// v3 — 使用 "&" 選擇器的 css 屬性
<Box css={{ "&:hover": { color: "blue.500" } }} />
步驟 7 — 元件遷移
重新命名的元件
| v2 | v3 |
|---|---|
Modal |
Dialog |
FormControl |
Field |
Select |
NativeSelect |
AlertDialog |
AlertDialog(複合,請參閱下方) |
Modal 是最常見的重新命名——每個 <Modal>、<ModalOverlay>、<ModalContent>、<ModalHeader>、<ModalBody>、<ModalFooter> 和 <ModalCloseButton> 都會變成 Dialog.* 複合部分:
// v2
<Modal isOpen={open} onClose={onClose}>
<ModalOverlay />
<ModalContent>
<ModalHeader>Title</ModalHeader>
<ModalBody>Body</ModalBody>
<ModalFooter><Button onClick={onClose}>Close</Button></ModalFooter>
</ModalContent>
</Modal>
// v3
<Dialog.Root open={open} onOpenChange={({ open }) => setOpen(open)}>
<Dialog.Backdrop />
<Dialog.Positioner>
<Dialog.Content>
<Dialog.Header><Dialog.Title>Title</Dialog.Title></Dialog.Header>
<Dialog.Body>Body</Dialog.Body>
<Dialog.Footer><Button onClick={() => setOpen(false)}>Close</Button></Dialog.Footer>
<Dialog.CloseTrigger />
</Dialog.Content>
</Dialog.Positioner>
</Dialog.Root>
複合元件重寫
v3 採用一致的複合元件 API。codemod 會處理許多這些情況,但複雜的自訂用法需要手動審查。
Checkbox
// v2
<Checkbox isChecked={val} onChange={fn}>Label</Checkbox>
// v3
<Checkbox.Root checked={val} onCheckedChange={fn}>
<Checkbox.Control><Checkbox.Indicator /></Checkbox.Control>
<Checkbox.Label>Label</Checkbox.Label>
</Checkbox.Root>
Progress
// v2
<Progress value={60} colorScheme="blue" />
// v3
<Progress.Root value={60} colorPalette="blue">
<Progress.Track><Progress.Range /></Progress.Track>
</Progress.Root>
Accordion
// v2
<Accordion><AccordionItem><AccordionButton /><AccordionPanel /></AccordionItem></Accordion>
// v3
<Accordion.Root>
<Accordion.Item value="item-1">
<Accordion.ItemTrigger />
<Accordion.ItemContent />
</Accordion.Item>
</Accordion.Root>
FormControl → Field
// v2
<FormControl isInvalid={!!error} isRequired>
<FormLabel>Email</FormLabel>
<Input type="email" />
<FormErrorMessage>{error}</FormErrorMessage>
<FormHelperText>We'll never share your email.</FormHelperText>
</FormControl>
// v3
<Field.Root invalid={!!error} required>
<Field.Label>Email</Field.Label>
<Input type="email" />
<Field.ErrorText>{error}</Field.ErrorText>
<Field.HelpText>We'll never share your email.</Field.HelpText>
</Field.Root>
所有 FormControl 子部分都對應到 Field.*:
FormLabel→Field.LabelFormErrorMessage→Field.ErrorTextFormHelperText→Field.HelpTextFormControl屬性isInvalid、isRequired、isDisabled→invalid、required、disabled
Dialog / Drawer / Menu / Tabs 遵循相同的複合模式:使用 ComponentName.Root、.Trigger、.Content、.Item 等。請查閱 Chakra UI v3 文件以了解每個元件的特定複合 API。
Next.js Image 和 Link(取代 @chakra-ui/next-js)
// v2 — @chakra-ui/next-js
import { LinkOverlay } from "@chakra-ui/next-js"
// v3 — asChild 模式
import NextLink from "next/link"
<ChakraLink asChild><NextLink href="/about">About</NextLink></ChakraLink>
import NextImage from "next/image"
<ChakraImage asChild><NextImage src="..." alt="..." /></ChakraImage>
步驟 8 — 主題遷移
styleConfig 和 multiStyleConfig → recipes
// v3 — 單一元件(recipe)
import { defineRecipe } from "@chakra-ui/react"
// v2
const buttonStyle = {
baseStyle: { fontWeight: "bold" },
variants: { solid: { bg: "blue.500" } },
defaultProps: { variant: "solid" },
}
const buttonRecipe = defineRecipe({
base: { fontWeight: "bold" },
variants: { variant: { solid: { bg: "blue.500" } } },
defaultVariants: { variant: "solid" },
})
// v3 — slot recipe
import { defineSlotRecipe } from "@chakra-ui/react"
// v2 — multiStyleConfig(多部分元件)
const cardStyle = multiStyleConfig({
parts: ["root", "header"],
baseStyle: { root: { bg: "white" }, header: { fontWeight: "bold" } },
})
const cardSlotRecipe = defineSlotRecipe({
slots: ["root", "header"],
base: { root: { bg: "white" }, header: { fontWeight: "bold" } },
})
自訂 tokens 的 Typegen
新增自訂 tokens、語意 tokens、recipes 或 slot recipes 後,執行 typegen 以保持 TypeScript 型別同步:
npx @chakra-ui/cli typegen ./theme.ts
複雜主題遷移 — 如果您要遷移包含許多自訂 tokens、語意 tokens 或多部分元件樣式的大型 v2 主題,請使用
chakra-ui-theming技能。它深入涵蓋完整的 token/recipe/slot-recipe API,是比本節更好的指南。
步驟 9 — Next.js 特定事項
App Router
- 將
<Provider>放在app/layout.tsx(伺服器元件——無需"use client") - 產生的
components/ui/provider.tsx已包含"use client" - 在
<html>中加入suppressHydrationWarning以防止色彩模式閃爍 - 不要將整個應用程式或 layout 包在
"use client"中
Pages Router
// pages/_app.js
import { Provider } from "@/components/ui/provider"
export default function App({ Component, pageProps }) {
return (
<Provider>
<Component {...pageProps} />
</Provider>
)
}
從 pages/_document.tsx 移除任何 ColorModeScript——它在 v3 中不使用。
步驟 10 — 驗證檢查清單
遷移完成後請逐一檢查:
- [ ] 重新安裝依賴:
npm install/pnpm install - [ ] TypeScript:
npx tsc --noEmit— 解決所有型別錯誤 - [ ] Lint:
npm run lint - [ ] 建置:
npm run build - [ ] 視覺驗證色彩模式切換(淺色 ↔ 深色)
- [ ] 測試互動元件:Dialog、Drawer、Menu、Tabs、Accordion
- [ ] 測試表單元件:Checkbox、Select/NativeSelect、Input、Radio
- [ ] 檢查關鍵頁面是否有視覺回歸
- [ ] 搜尋程式碼庫中殘留的 v2 匯入:
grep -r "ColorModeScript\|useColorModeValue\|extendTheme\|styleConfig\|@chakra-ui/icons\|@chakra-ui/next-js" src/
釐清問題(當內容不明確時)
如果使用者的版本、框架或範圍不明確,請詢問:
- 「您目前使用的
@chakra-ui/react版本是什麼?」 - 「您使用的是 Next.js App Router、Pages Router、Vite 還是純 React?」
- 「您要遷移整個程式碼庫還是僅特定元件?」
如果您在未詢問的情況下繼續,請清楚說明您的假設。





