Build faster with Premium Chakra UI Components 💎

Learn more
Skip to Content
DocsPlaygroundGuidesBlog
Sponsor

Recipes

Learn how to customize recipes and slot recipes in Chakra UI

info
Please read the overview first to learn how to properly customize the styling engine, and get type safety.

Recipes

Extending variants

Use the defineRecipe function to define a recipe override.

Here's an example of extending the Button to add a new xl size

theme.ts

const buttonRecipe = defineRecipe({
  variants: {
    size: {
      xl: {
        fontSize: "lg",
        px: 6,
        py: 3,
      },
    },
  },
})

const customConfig = defineConfig({
  theme: {
    recipes: {
      button: buttonRecipe,
    },
  },
})

export const system = createSystem(defaultConfig, customConfig)

Then you can use the new size variant in your components.

<Button size="xl">Click me</Button>

Adding new variant

Use the defineRecipe function to define a new recipe variant.

Here's an example of defining a boolean variant called raised.

theme.ts

const buttonRecipe = defineRecipe({
  variants: {
    raised: {
      true: {
        boxShadow: "md",
      },
    },
  },
})

const customConfig = defineConfig({
  theme: {
    recipes: {
      button: buttonRecipe,
    },
  },
})

export const system = createSystem(defaultConfig, customConfig)

Then you can use the new variant in your components.

<Button raised>Click me</Button>

Custom recipe

Use the defineRecipe function to define a custom recipe all together.

Here's an example of defining a custom recipe called Title

theme.ts

const titleRecipe = defineRecipe({
  baseStyle: {
    fontWeight: "bold",
    letterSpacing: "tight",
  },
  variants: {
    size: {
      md: { fontSize: "xl" },
      lg: { fontSize: "2xl" },
    },
  },
})

const customConfig = defineConfig({
  theme: {
    recipes: {
      title: titleRecipe,
    },
  },
})

export const system = createSystem(defaultConfig, customConfig)

Then, use the new recipe to create a components

const Title = (props) => {
  const recipe = useRecipe({ key: "title" })
  const styles = recipe({ size: "lg" })
  return <Box as="h1" css={styles} {...props} />
}

Slot Recipes

To effectively override an existing slot recipe, we recommend connecting to its anatomy. Slot recipes are added to the theme.slotRecipes object.

Extending variants

Here's an example of how to extend the Alert slot recipe to create an xl size.

theme.ts

import { alertAnatomy } from "@chakra-ui/react/anatomy"

const alertSlotRecipe = defineSlotRecipe({
  slots: alertAnatomy.keys(),
  variants: {
    size: {
      xl: {
        root: {
          fontSize: "lg",
          px: 6,
          py: 3,
        },
      },
    },
  },
})

const customConfig = defineConfig({
  theme: {
    slotRecipes: {
      alert: alertSlotRecipe,
    },
  },
})

export const system = createSystem(defaultConfig, customConfig)

Then you can use the new size variant in your components.

<Alert size="xl" title="..." />

Adding new variant

Here's an example of how to extend the Alert slot recipe to add a new variant called shape.

theme.ts

import { alertAnatomy } from "@chakra-ui/react/anatomy"

const alertSlotRecipe = defineSlotRecipe({
  slots: alertAnatomy.keys(),
  variants: {
    shape: {
      rounded: {
        root: { borderRadius: "full" },
      },
    },
  },
})

const customConfig = defineConfig({
  theme: {
    slotRecipes: {
      alert: alertSlotRecipe,
    },
  },
})

export const system = createSystem(defaultConfig, customConfig)

Then you can use the new variant in your components.

<Alert shape="rounded" title="..." />

Custom recipe

Here's an example of how to define a custom slot recipe called Navbar.

theme.ts

const navbarSlotRecipe = defineSlotRecipe({
  slots: ["root", "badge", "icon"],
  base: {
    root: {
      bg: "blue.500",
      color: "white",
      px: 4,
      py: 2,
    },
    badge: {
      borderRadius: "full",
      px: 2,
      py: 1,
    },
  },
})

const customConfig = defineConfig({
  theme: {
    slotRecipes: {
      navbar: navbarSlotRecipe,
    },
  },
})

export const system = createSystem(defaultConfig, customConfig)

Then you can use the new recipe to create a components

const Navbar = (props) => {
  const recipe = useSlotRecipe({ key: "navbar" })
  const styles = recipe()
  return (
    <Box css={styles.root}>
      {props.children}
      <Box css={styles.badge} />
      <Box css={styles.icon} />
    </Box>
  )
}

Previous

Global CSS

Next

Sizes