This is the full developer documentation for Chakra UI v3. # AbsoluteCenter ```tsx import { AbsoluteCenter, Box } from "@chakra-ui/react" export const AbsoluteCenterBasic = () => { return ( Centered Content ) } ``` ## Usage The `AbsoluteCenter` component uses the `position: absolute` strategy to center its child element relative to its parent. > The parent element must have `position: relative` for proper positioning. ```jsx import { AbsoluteCenter } from "@chakra-ui/react" ``` ```jsx Centered Content ``` ## Examples ### Axis Control Control which axis to center on using the `axis` prop. Options are `horizontal`, `vertical`, or `both` (default). ```tsx import { AbsoluteCenter, Box, For, Text, VStack } from "@chakra-ui/react" export const AbsoluteCenterWithAxis = () => { return ( {(axis) => ( {``} {axis} )} ) } ``` ### With Content Use `AbsoluteCenter` with various content types like icons, badges, and status indicators. ```tsx import { AbsoluteCenter, Box } from "@chakra-ui/react" import { LuHeart } from "react-icons/lu" export const AbsoluteCenterWithContent = () => { return ( ) } ``` ### Overlay Usage Perfect for creating loading overlays or modal-like content that needs to be centered over existing content. ```tsx import { AbsoluteCenter, Box, HStack, Spinner, Text } from "@chakra-ui/react" const Overlay = () => ( Loading... ) export const AbsoluteCenterWithOverlay = () => { return ( Some content that is being loaded... ) } ``` ### RTL Support `AbsoluteCenter` automatically handles right-to-left (RTL) layouts by adjusting the horizontal positioning and transforms appropriately. ```tsx import { AbsoluteCenter, Box, For, HStack, Span, Text, VStack, } from "@chakra-ui/react" export const AbsoluteCenterWithRtl = () => { return ( {(axis) => ( RTL ({axis}) البداية )} ) } ``` ## Props | Prop | Default | Type | Description | | --- | --- | --- | --- | | axis | undefined | `'horizontal' \| 'vertical' \| 'both' \| undefined` | undefined | | as | undefined | `React.ElementType` | The underlying element to render. | | asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. | # Accordion ```tsx import { Accordion, Span } from "@chakra-ui/react" export const AccordionBasic = () => { return ( {items.map((item, index) => ( {item.title} {item.text} ))} ) } const items = [ { value: "a", title: "First Item", text: "Some value 1..." }, { value: "b", title: "Second Item", text: "Some value 2..." }, { value: "c", title: "Third Item", text: "Some value 3..." }, ] ``` ## Usage ```tsx import { Accordion } from "@chakra-ui/react" ``` ```tsx ``` ## Examples ### Controlled Set the accordion that shows up by default. ```tsx "use client" import { Accordion, Span, Stack, Text } from "@chakra-ui/react" import { useState } from "react" export const AccordionControlled = () => { const [value, setValue] = useState(["second-item"]) return ( Expanded: {value.join(", ")} setValue(e.value)}> {items.map((item, index) => ( {item.title} {item.text} ))} ) } const items = [ { value: "first-item", title: "First Item", text: "Some value 1..." }, { value: "second-item", title: "Second Item", text: "Some value 2..." }, { value: "third-item", title: "Third Item", text: "Some value 3..." }, ] ``` ### With Icon Here's an example of rendering a custom icon in each accordion item. ```tsx import { Accordion, Heading, Icon, Stack } from "@chakra-ui/react" import { LuChartBarStacked, LuTags } from "react-icons/lu" export const AccordionWithIcon = () => { return ( Product details {items.map((item) => ( {item.icon} {item.title} {item.content} ))} ) } const items = [ { value: "info", icon: , title: "Product Info", content: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur nec odio vel dui euismod fermentum.", }, { value: "stats", icon: , title: "Stats", content: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur nec odio vel dui euismod fermentum.", }, ] ``` ### Expand Multiple Items Use the `multiple` prop to allow multiple items to be expanded at once. ```tsx import { Accordion, Span } from "@chakra-ui/react" export const AccordionWithMultiple = () => { return ( {items.map((item, index) => ( {item.title} {item.text} ))} ) } const items = [ { value: "a", title: "First Item", text: "Some value 1..." }, { value: "b", title: "Second Item", text: "Some value 2..." }, { value: "c", title: "Third Item", text: "Some value 3..." }, ] ``` ### Sizes Use the `size` prop to change the size of the accordion. ```tsx import { Accordion, For, Span, Stack, Text } from "@chakra-ui/react" export const AccordionSizes = () => { return ( {(size) => ( {size} {items.map((item, index) => ( {item.title} {item.text} ))} )} ) } const items = [ { value: "a", title: "First Item", text: "Some value 1..." }, { value: "b", title: "Second Item", text: "Some value 2..." }, { value: "c", title: "Third Item", text: "Some value 3..." }, ] ``` ### Variants Use the `variant` prop to change the visual style of the accordion. Values can be either `outline`, `subtle`, `enclosed` or `plain`. ```tsx import { Accordion, For, Span, Stack, Text } from "@chakra-ui/react" export const AccordionVariants = () => { return ( {(variant) => ( {variant} {items.map((item, index) => ( {item.title} {item.text} ))} )} ) } const items = [ { value: "a", title: "First Item", text: "Some value 1..." }, { value: "b", title: "Second Item", text: "Some value 2..." }, { value: "c", title: "Third Item", text: "Some value 3..." }, ] ``` ### Disabled Item Pass the `disabled` prop to any `Accordion.Item` to prevent it from being expanded or collapsed. ```tsx import { Accordion, Span } from "@chakra-ui/react" export const AccordionWithDisabledItem = () => { return ( {items.map((item, index) => ( {item.title} {item.text} ))} ) } const items = [ { value: "a", title: "First Item", text: "Some value 1..." }, { value: "b", title: "Second Item", text: "Some value 2..." }, { value: "c", title: "Third Item", text: "Some value 3...", disabled: true }, ] ``` ### With Avatar Here's an example of composing an accordion with an avatar. ```tsx import { Accordion, Avatar, Badge, HStack } from "@chakra-ui/react" import { LuTrophy } from "react-icons/lu" import { LoremIpsum } from "react-lorem-ipsum" export const AccordionWithAvatar = () => { return ( {items.map((item, index) => ( {item.name}{" "} {item.topRated && ( Top Rated )} {item.bio} ))} ) } const items = [ { name: "Alex", bio: , image: "https://i.pravatar.cc/150?u=a", topRated: false, }, { name: "Benji", bio: , image: "https://i.pravatar.cc/150?u=b", topRated: true, }, { name: "Charlie", bio: , image: "https://i.pravatar.cc/150?u=c", topRated: false, }, ] ``` ### With Subtext Here's an example of adding a subtext to an accordion item. ```tsx import { Accordion, Stack, Text } from "@chakra-ui/react" import { LoremIpsum } from "react-lorem-ipsum" const items = [ { value: "a", title: "First Item", text: }, { value: "b", title: "Second Item", text: }, { value: "c", title: "Third Item", text: }, ] export const AccordionWithSubtext = () => { return ( {items.map((item, index) => ( {item.title} Click to expand {item.text} ))} ) } ``` ### With Actions Here's an example of adding actions to an accordion item trigger. ```tsx import { AbsoluteCenter, Accordion, Box, Button, Span } from "@chakra-ui/react" import LoremIpsum from "react-lorem-ipsum" export const AccordionWithActions = () => { return ( {items.map((item, index) => ( {item.title} {item.text} ))} ) } const items = [ { value: "a", title: "First Item", text: }, { value: "b", title: "Second Item", text: }, { value: "c", title: "Third Item", text: }, ] ``` ### Styling Expanded Style Pass the `_open` pseudo selector to the `Accordion.ItemTrigger` or `Accordion.Item` to attach styles to it when expanded. ```tsx import { Accordion, Span } from "@chakra-ui/react" export const AccordionWithExpandedStyle = () => { return ( {items.map((item, index) => ( {item.title} {item.text} ))} ) } const items = [ { value: "a", title: "First Item", text: "Click the accordion button to see a different style when expanded.", }, { value: "b", title: "Second Item", text: "The trigger background changes to teal with white text when expanded.", }, { value: "c", title: "Third Item", text: "You can use any style props with the _open pseudo selector.", }, ] ``` ## Guides ### Accessing Root State Use `useAccordionContext` to access the accordion state at the root level: ```tsx import { useAccordionContext } from "@chakra-ui/react" const AccordionValueText = () => { const accordion = useAccordionContext() return Opened: {accordion.value.join(", ")} } // Usage const Demo = () => ( {/* ... accordion items */} ) ``` ### Accessing Item State Use `useAccordionItemContext` to access the state of a specific accordion item: ```tsx import { useAccordionItemContext } from "@chakra-ui/react" const AccordionItemStatus = () => { const item = useAccordionItemContext() return ( {item.open ? "Expanded" : "Collapsed"} ) } // Usage const Demo = () => ( Content ) ``` ## Props ### Root | Prop | Default | Type | Description | | --- | --- | --- | --- | | hideMode | 'display-none' | `HideMode` | How to hide content when mounted but not present. - `'display-none'`: HTML `hidden` attribute. Effects stay alive. - `'activity'`: React 19 ``. Effects pause. Requires React 19+. | | orientation | vertical | `'horizontal' \| 'vertical'` | The orientation of the accordion items. | | colorPalette | gray | `'gray' \| 'red' \| 'orange' \| 'yellow' \| 'green' \| 'teal' \| 'blue' \| 'cyan' \| 'purple' \| 'pink'` | The color palette of the component | | variant | outline | `'outline' \| 'subtle' \| 'enclosed' \| 'plain'` | The variant of the component | | size | md | `'sm' \| 'md' \| 'lg'` | The size of the component | | as | undefined | `React.ElementType` | The underlying element to render. | | asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. | | unstyled | undefined | `boolean` | Whether to remove the component's style. | | collapsible | false | `boolean` | Whether an accordion item can be closed after it has been expanded. | | defaultValue | undefined | `string[]` | The initial value of the expanded accordion items. Use when you don't need to control the value of the accordion. | | disabled | undefined | `boolean` | Whether the accordion items are disabled | | id | undefined | `string` | The unique identifier of the machine. | | ids | undefined | `Partial<{\n root: string\n item: (value: string) => string\n itemContent: (value: string) => string\n itemTrigger: (value: string) => string\n}>` | The ids of the elements in the accordion. Useful for composition. | | lazyMount | false | `boolean` | Whether to enable lazy mounting | | multiple | false | `boolean` | Whether multiple accordion items can be expanded at the same time. | | onFocusChange | undefined | `(details: FocusChangeDetails) => void` | The callback fired when the focused accordion item changes. | | onValueChange | undefined | `(details: ValueChangeDetails) => void` | The callback fired when the state of expanded/collapsed accordion items changes. | | unmountOnExit | false | `boolean` | Whether to unmount on exit. | | value | undefined | `string[]` | The controlled value of the expanded accordion items. | ### Item | Prop | Default | Type | Description | | --- | --- | --- | --- | | value | undefined | `string` | The value of the accordion item. | | as | undefined | `React.ElementType` | The underlying element to render. | | asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. | | disabled | undefined | `boolean` | Whether the accordion item is disabled. | ## Explorer Explore the `Accordion` component parts interactively. Click on parts in the sidebar to highlight them in the preview. # Action Bar ```tsx "use client" import { ActionBar, Button, Checkbox, Portal } from "@chakra-ui/react" import { useState } from "react" import { LuShare, LuTrash2 } from "react-icons/lu" export const ActionBarBasic = () => { const [checked, setChecked] = useState(false) return ( <> setChecked(!!e.checked)}> Show Action bar 2 selected ) } ``` ## Usage The action bar is designed to be controlled by table or checkbox selections. It provides a set of actions that can be performed on the selected items. ```tsx import { ActionBar } from "@chakra-ui/react" ``` ```tsx ``` ## Examples ### Close Trigger Render the `ActionBar.CloseTrigger` to close the action bar, and pass the `onOpenChange` handler to control the visibility of the action bar. > The `open` and `onOpenChange` props control the visibility of the action bar. ```tsx "use client" import { ActionBar, Button, Checkbox, CloseButton, Portal, } from "@chakra-ui/react" import { useState } from "react" import { LuShare, LuTrash2 } from "react-icons/lu" export const ActionBarWithCloseTrigger = () => { const [checked, setChecked] = useState(false) return ( <> setChecked(!!e.checked)} > Show Action bar setChecked(e.open)} closeOnInteractOutside={false} > 2 selected ) } ``` ### Within Dialog Here's an example of composing the `ActionBar` and the `Dialog` to perform a delete action on a set of selected items. > Press the `Delete projects` button to open the dialog. ```tsx "use client" import { ActionBar, Button, Checkbox, Dialog, Portal } from "@chakra-ui/react" import { useState } from "react" import { LuSquarePlus, LuTrash2 } from "react-icons/lu" export const ActionBarWithDialog = () => { const [checked, setChecked] = useState(false) return ( <> setChecked(!!e.checked)}> Check to select projects 4 selected Delete projects Are you sure you want to delete 4 projects? ) } ``` ### Placement Use the `placement` prop to control the position of the action bar. The action bar supports three placement options: `bottom` (default), `bottom-start`, and `bottom-end`. ```tsx "use client" import { ActionBar, Button, Portal, SegmentGroup, Text, VStack, } from "@chakra-ui/react" import { useState } from "react" import { LuShare, LuTrash2 } from "react-icons/lu" export const ActionBarPlacement = () => { const [placement, setPlacement] = useState< "bottom" | "bottom-start" | "bottom-end" >("bottom") const [open, setOpen] = useState(false) return ( Placement: setPlacement(e.value as "bottom" | "bottom-start" | "bottom-end") } > 3 selected ) } ``` ## Props ### Root | Prop | Default | Type | Description | | --- | --- | --- | --- | | autoFocus | true | `boolean` | Whether to automatically set focus on the first focusable content within the popover when opened. | | closeOnEscape | true | `boolean` | Whether to close the popover when the escape key is pressed. | | closeOnInteractOutside | true | `boolean` | Whether to close the popover when the user clicks outside of the popover. | | hideMode | 'display-none' | `HideMode` | How to hide content when mounted but not present. - `'display-none'`: HTML `hidden` attribute. Effects stay alive. - `'activity'`: React 19 ``. Effects pause. Requires React 19+. | | portalled | true | `boolean` | Whether the popover is portalled. This will proxy the tabbing behavior regardless of the DOM position of the popover content. | | restoreFocus | true | `boolean` | Whether to restore focus to the element that had focus before the popover was opened. | | size | md | `'xs' \| 'sm' \| 'md' \| 'lg'` | The size of the component | | as | undefined | `React.ElementType` | The underlying element to render. | | asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. | | unstyled | undefined | `boolean` | Whether to remove the component's style. | | defaultOpen | undefined | `boolean` | The initial open state of the popover when rendered. Use when you don't need to control the open state of the popover. | | defaultTriggerValue | undefined | `string` | The initial trigger value when rendered. Use when you don't need to control the trigger value. | | finalFocusEl | undefined | `() => MaybeElement` | Element to receive focus when the popover is closed. | | id | undefined | `string` | The unique identifier of the machine. | | ids | undefined | `Partial<{\n anchor: string\n trigger: string \| ((value?: string \| undefined) => string)\n content: string\n title: string\n description: string\n closeTrigger: string\n positioner: string\n arrow: string\n}>` | The ids of the elements in the popover. Useful for composition. | | immediate | undefined | `boolean` | Whether to synchronize the present change immediately or defer it to the next frame | | initialFocusEl | undefined | `() => HTMLElement \| null` | The element to focus on when the popover is opened. | | lazyMount | false | `boolean` | Whether to enable lazy mounting | | modal | false | `boolean` | Whether the popover should be modal. When set to `true`: - interaction with outside elements will be disabled - only popover content will be visible to screen readers - scrolling is blocked - focus is trapped within the popover | | onEscapeKeyDown | undefined | `(event: KeyboardEvent) => void` | Function called when the escape key is pressed | | onExitComplete | undefined | `VoidFunction` | Function called when the animation ends in the closed state | | onFocusOutside | undefined | `(event: FocusOutsideEvent) => void` | Function called when the focus is moved outside the component | | onInteractOutside | undefined | `(event: InteractOutsideEvent) => void` | Function called when an interaction happens outside the component | | onOpenChange | undefined | `(details: OpenChangeDetails) => void` | Function invoked when the popover opens or closes | | onPointerDownOutside | undefined | `(event: PointerDownOutsideEvent) => void` | Function called when the pointer is pressed down outside the component | | onRequestDismiss | undefined | `(event: LayerDismissEvent) => void` | Function called when this layer is closed due to a parent layer being closed | | onTriggerValueChange | undefined | `(details: TriggerValueChangeDetails) => void` | Function called when the trigger value changes. | | open | undefined | `boolean` | The controlled open state of the popover | | persistentElements | undefined | `(() => Element \| null)[]` | Returns the persistent elements that: - should not have pointer-events disabled - should not trigger the dismiss event | | positioning | undefined | `PositioningOptions` | The user provided options used to position the popover content | | present | undefined | `boolean` | Whether the node is present (controlled by the user) | | skipAnimationOnMount | false | `boolean` | Whether to allow the initial presence animation. | | translations | undefined | `IntlTranslations` | Specifies the localized strings that identifies the accessibility elements and their states | | triggerValue | undefined | `string` | The controlled trigger value | | unmountOnExit | false | `boolean` | Whether to unmount on exit. | # Alert ```tsx import { Alert } from "@chakra-ui/react" export const AlertBasic = () => { return ( This is the alert title ) } ``` ## Usage ```jsx import { Alert } from "@chakra-ui/react" ``` ```jsx ``` :::info If you prefer a closed component composition, check out the [snippet below](#closed-component). ::: ## Examples ### Description Render the `Alert.Description` component to provide additional context to the alert. ```tsx import { Alert } from "@chakra-ui/react" export const AlertWithDescription = () => { return ( Invalid Fields Your form has some errors. Please fix them and try again. ) } ``` ### Status Change the status of the alerts by passing the `status` prop. This affects the color scheme and icon used. Alert supports `error`, `success`, `warning`, and `info` statuses. ```tsx import { Alert, Stack } from "@chakra-ui/react" export const AlertWithStatus = () => { return ( There was an error processing your request Chakra is going live on August 30th. Get ready! Seems your account is about expire, upgrade now Data uploaded to the server. Fire on! ) } ``` ### Variants Use the `variant` prop to change the visual style of the alert. Values can be either `subtle`, `solid`, `outline`, `surface` ```tsx import { Alert, Stack } from "@chakra-ui/react" export const AlertWithVariants = () => { return ( Data uploaded to the server. Fire on! Data uploaded to the server. Fire on! Data uploaded to the server. Fire on! Data uploaded to the server. Fire on! ) } ``` ### With Close Button Here's and example of how to compose the `Alert` with a close button. ```tsx import { Alert, CloseButton } from "@chakra-ui/react" export const AlertWithCloseButton = () => { return ( Success! Your application has been received. We will review your application and respond within the next 48 hours. ) } ``` ### With Spinner Here's and example of how to compose the `Alert` with a spinner. ```tsx import { Alert, Spinner } from "@chakra-ui/react" export const AlertWithSpinner = () => { return ( We are loading something ) } ``` ### Custom Icon Use the `icon` prop to pass a custom icon to the alert. This will override the default icon for the alert status. ```tsx import { Alert } from "@chakra-ui/react" import { LuAlarmClockPlus } from "react-icons/lu" export const AlertWithCustomIcon = () => { return ( Submitting this form will delete your account ) } ``` ### Color Palette Override The default colorPalette is inferred from the `status` prop. To override the color palette, pass the `colorPalette` prop. ```tsx import { Alert } from "@chakra-ui/react" export const AlertWithColorPaletteOverride = () => { return ( This is an info alert but shown as teal ) } ``` ### Customization You can style the `Alert` component using style props. ```tsx import { Alert, Link, Stack } from "@chakra-ui/react" import { LuPercent } from "react-icons/lu" export const AlertWithCustomization = () => { return ( Black Friday Sale (20% off) Upgrade your plan to get access to the sale. Upgrade Heads up: Black Friday Sale (20% off) ) } ``` ### Closed Component Here's how to setup the `Alert` for a closed component composition. If you want to automatically add the closed component to your project, run the command: ```bash npx @chakra-ui/cli snippet add alert ``` ## Props ### Root | Prop | Default | Type | Description | | --- | --- | --- | --- | | colorPalette | gray | `'gray' \| 'red' \| 'orange' \| 'yellow' \| 'green' \| 'teal' \| 'blue' \| 'cyan' \| 'purple' \| 'pink'` | The color palette of the component | | status | info | `'info' \| 'warning' \| 'success' \| 'error' \| 'neutral'` | The status of the component | | variant | subtle | `'subtle' \| 'surface' \| 'outline' \| 'solid'` | The variant of the component | | size | md | `'sm' \| 'md' \| 'lg'` | The size of the component | | as | undefined | `React.ElementType` | The underlying element to render. | | asChild | undefined | `boolean` | Use the provided child element as the default rendered element, combining their props and behavior. | | unstyled | undefined | `boolean` | Whether to remove the component's style. | | inline | false | `'true' \| 'false'` | The inline of the component | ## Explorer Explore the `Alert` component parts interactively. Click on parts in the sidebar to highlight them in the preview. # Aspect Ratio ```tsx import { AspectRatio, Center } from "@chakra-ui/react" export const AspectRatioBasic = () => { return (
16 / 9
) } ``` ## Usage The `ratio` prop overrides the original aspect ratios of `AspectRatio`'s child content, accepting only numeric values, not strings. ```jsx import { AspectRatio } from "@chakra-ui/react" ``` ```jsx ) } ``` ### Setup provider Wrap your application with the `Provider` component generated in the `components/ui/provider` component at the root of your application. This provider composes the following: - `ChakraProvider` from `@chakra-ui/react` for the styling system - `ThemeProvider` from `next-themes` for color mode ```jsx import { Provider } from "@/components/ui/provider" import React from "react" import ReactDOM from "react-dom/client" import App from "./App" ReactDOM.createRoot(document.getElementById("root")!).render( , ) ``` ### Use the IframeProvider At any component in your application, wrap it with the `IframeProvider` component to render it inside the iframe. ```tsx title="src/App.tsx" import { Button, Container, Heading, Stack } from "@chakra-ui/react" import { IframeProvider } from "./components/ui/iframe-provider" function App() { return ( Outside Iframe Inside Iframe ) } export default App ``` ::: ## Customization If you created a custom theme using the `createSystem` function, ensure it's passed to the `IframeProvider` and `Provider` components to ensure it's used inside the iframe. For example, let's say you created a custom theme: ```ts export const system = createSystem(defaultConfig, { theme: { colors: {} }, }) ``` Then, pass it to the `IframeProvider` and `Provider` components: ```tsx {/* ... */} ``` # Using Chakra UI in Shadow DOM When developing extensions for browsers or using Chakra as part of a large project, leveraging the Shadow DOM is useful for style and logic encapsulation. ## Template Use the following template to get started quickly :::card-group ::: ## Installation > The minimum node version required is Node.20.x :::steps ### Install dependencies ```bash npm i @chakra-ui/react @emotion/react @emotion/cache react-shadow ``` The additional packages used are: - `react-shadow` used to create a Shadow DOM easily - `@emotion/cache` used to create a custom insertion point for styles ### Add snippets Snippets are pre-built components that you can use to build your UI faster. Using the `@chakra-ui/cli` you can add snippets to your project. ```bash npx @chakra-ui/cli snippet add ``` ### Update tsconfig If you're using TypeScript, you need to update the `compilerOptions` in the tsconfig file to include the following options: ```json { "compilerOptions": { "module": "ESNext", "moduleResolution": "Bundler", "skipLibCheck": true, "paths": { "@/*": ["./src/*"] } } } ``` ### Configure style engine Create a `system.ts` file in the root of your project and configure the style engine. ```tsx title="components/ui/system.ts" import { createSystem, defaultConfig, defineConfig } from "@chakra-ui/react" const varRoot = ":host" const config = defineConfig({ cssVarsRoot: varRoot, conditions: { light: `${varRoot} &, .light &`, }, preflight: { scope: varRoot }, globalCss: { [varRoot]: defaultConfig.globalCss?.html ?? {}, }, }) export const system = createSystem(defaultConfig, config) ``` > **Good to know**: The main purpose of the `system.ts` file is to configure the > style engine to target the Shadow DOM. ### Setup provider Update the generated `components/ui/provider` component with the `Provider` component. This provider composes the following: - `ChakraProvider` from `@chakra-ui/react` for the styling system - `EnvironmentProvider` from `react-shadow` to ensure Chakra components query the DOM correctly - `CacheProvider` from `@emotion/react` to provide the custom insertion point - `ThemeProvider` from `next-themes` for color mode ```tsx title="components/ui/provider.tsx" "use client" import { ChakraProvider, EnvironmentProvider } from "@chakra-ui/react" import createCache from "@emotion/cache" import { CacheProvider } from "@emotion/react" import { ThemeProvider, type ThemeProviderProps } from "next-themes" import { useEffect, useState } from "react" import root from "react-shadow/emotion" import { system } from "./system" export function Provider(props: ThemeProviderProps) { const [shadow, setShadow] = useState(null) const [cache, setCache] = useState | null>( null, ) useEffect(() => { if (!shadow?.shadowRoot || cache) return const emotionCache = createCache({ key: "root", container: shadow.shadowRoot, }) setCache(emotionCache) }, [shadow, cache]) return ( {shadow && cache && ( shadow.shadowRoot ?? document}> )} ) } ``` ### Use the provider Wrap your application with the `Provider` component generated in the `components/ui/provider` component at the root of your application. ```tsx title="src/main.tsx" {1,8,10} import { Provider } from "@/components/ui/provider" import { StrictMode } from "react" import { createRoot } from "react-dom/client" import App from "./App.tsx" createRoot(document.getElementById("root")!).render( , ) ``` ### Enjoy! With the power of the snippets and the primitive components from Chakra UI, you can build your UI faster. ```tsx import { Button, HStack } from "@chakra-ui/react" export default function App() { return ( ) } ``` ::: # Using Chakra UI in Next.js (App) ## Compatibility Chakra UI works with Next.js 15 and 16. Chakra UI doesn't lock you to a specific Next.js major version. If your project uses supported React and Emotion versions, this guide applies. The templates in this repo may pin an older Next.js major for stability. You can upgrade `next` to the latest major in your app. ## Templates Use one of the following templates to get started quickly. The templates are configured correctly to use Chakra UI. :::card-group ::: ## Installation > The minimum node version required is Node.20.x :::steps ### Install dependencies ```bash npm i @chakra-ui/react @emotion/react ``` ### Add snippets Snippets are pre-built components that you can use to build your UI faster. Using the `@chakra-ui/cli` you can add snippets to your project. ```bash npx @chakra-ui/cli snippet add ``` ### Update tsconfig If you're using TypeScript, you need to update the `compilerOptions` in the tsconfig file to include the following options: ```json { "compilerOptions": { "target": "ESNext", "module": "ESNext", "moduleResolution": "Bundler", "skipLibCheck": true, "paths": { "@/*": ["./src/*"] } } } ``` > If you're using JavaScript, create a `jsconfig.json` file and add the above > code to the file. ### Setup provider Wrap your application with the `Provider` component generated in the `components/ui/provider` component at the root of your application. This provider composes the following: - `ChakraProvider` from `@chakra-ui/react` for the styling system - `ThemeProvider` from `next-themes` for color mode ```tsx title="app/layout.tsx" {1,6,8} import { Provider } from "@/components/ui/provider" export default function RootLayout(props: { children: React.ReactNode }) { const { children } = props return ( {children} ) } ``` > Adding the `suppressHydrationWarning` prop to the `html` element is required > to prevent the warning about the `next-themes` library. ### Optimize Bundle We recommend using the `experimental.optimizePackageImports` feature in Next.js to optimize your bundle size by loading only the modules that you are actually using. ```tsx title="next.config.mjs" {3} export default { experimental: { optimizePackageImports: ["@chakra-ui/react"], }, } ``` This also helps to resolve warnings like: ```sh [webpack.cache.PackFileCacheStrategy] Serializing big strings (xxxkiB) ``` ### Stream through Suspense (optional) Skip this unless you stream UI through ``. You need it when Chakra components first appear inside a streamed `` chunk. If you enable [Cache Components](https://nextjs.org/docs/app/api-reference/config/next-config-js/cacheComponents) in Next.js 16, that is the default. Install `@emotion/cache` and add this registry: ```tsx title="components/ui/emotion-registry.tsx" "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 (