Next.js (App)

A guide for installing and using Yamada UI with Next.js app directory.

Installation

  • 1

    Create application

    Create Next.js application.

    pnpm create next-app my-app --typescript
    
  • 2

    Setup

    Running the command will create the necessary files and folders in your project.

    pnpm dlx @yamada-ui/cli init
    
  • 3

    Install the package

    Install @workspaces/ui to your application.

    pnpm add "@workspaces/ui@workspace:*"
    
  • 4

    Add provider

    After installing, add UIProvider to the root of your application. To suppress hydration errors, add suppressHydrationWarning to the html and body tags.

    layout.tsx

    import { UIProvider } from "@yamada-ui/react"
    
    export default function RootLayout({
      children,
    }: {
      children: React.ReactNode
    }) {
      return (
        <html lang="en" suppressHydrationWarning>
          <body suppressHydrationWarning>
            <UIProvider>{children}</UIProvider>
          </body>
        </html>
      )
    }
    
  • 5

    Use components

    After adding UIProvider, you can use the components in your application.

    page.tsx

    import { Button } from "@workspaces/ui"
    
    export default function Home() {
      return <Button>Click me!</Button>
    }
    

    That's it! You've successfully set up Yamada UI.

Scripts

ColorModeScript

To use Color Mode, you need to add ColorModeScript to the body to ensure it works correctly.

This is because color mode is implemented using localStorage or cookies, and adding the script ensures proper synchronization when the page loads.

layout.tsx

import { UIProvider, ColorModeScript } from "@workspaces/ui"

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="en" suppressHydrationWarning>
      <body suppressHydrationWarning>
        <ColorModeScript />

        <UIProvider>{children}</UIProvider>
      </body>
    </html>
  )
}

If you change the defaultColorMode in your config, set the defaultValue prop on ColorModeScript.

layout.tsx

import { UIProvider, ColorModeScript } from "@workspaces/ui"
import { config } from "@workspaces/theme"

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="en" suppressHydrationWarning>
      <body suppressHydrationWarning>
        <ColorModeScript defaultValue={config.defaultColorMode} />

        <UIProvider config={config}>{children}</UIProvider>
      </body>
    </html>
  )
}

ThemeSchemeScript

To use theme switching, you need to add ThemeSchemeScript to the body to ensure it works correctly.

This is because theme switching is implemented using localStorage or cookies, and adding the script ensures proper synchronization when the page loads.

layout.tsx

import { UIProvider, ThemeSchemeScript } from "@workspaces/ui"

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="en" suppressHydrationWarning>
      <body suppressHydrationWarning>
        <ThemeSchemeScript />

        <UIProvider>{children}</UIProvider>
      </body>
    </html>
  )
}

If you change the defaultThemeScheme in your config, set the defaultValue prop on ThemeSchemeScript.

layout.tsx

import { UIProvider, ThemeSchemeScript } from "@workspaces/ui"
import { config } from "@workspaces/theme"

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="en" suppressHydrationWarning>
      <body suppressHydrationWarning>
        <ThemeSchemeScript defaultValue={config.defaultThemeScheme} />

        <UIProvider config={config}>{children}</UIProvider>
      </body>
    </html>
  )
}

Use cookies

Using cookies allows you to ensure proper operation even on server-side rendering.

layout.tsx

import { UIProvider, ColorModeScript, ThemeSchemeScript } from "@workspaces/ui"
import { cookies } from "next/headers"

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  const cookieStore = await cookies()

  return (
    <html lang="en" suppressHydrationWarning>
      <body suppressHydrationWarning>
        <ColorModeScript type="cookie" />
        <ThemeSchemeScript type="cookie" />

        <UIProvider cookie={cookieStore.toString()}>{children}</UIProvider>
      </body>
    </html>
  )
}

Component Integration

You can integrate Next.js components such as Link and Image with Yamada UI components.

"use client"

import type {
  ButtonProps,
  HTMLRefAttributes,
  IconButtonProps,
  LinkProps,
  Merge,
} from "@yamada-ui/react"
import type { LinkProps as OriginalLinkProps } from "next/link"
import type { FC } from "react"
import { Button, IconButton, Link } from "@yamada-ui/react"
import OriginalLink from "next/link"

export interface NextLinkProps
  extends Omit<Merge<OriginalLinkProps, LinkProps>, "as" | "ref"> {}

export const NextLink: FC<NextLinkProps> = (props) => {
  return <Link as={OriginalLink} {...props} />
}

export interface NextLinkButtonProps
  extends Omit<Merge<OriginalLinkProps, ButtonProps>, "as" | "ref">,
    HTMLRefAttributes<"a"> {}

export const NextLinkButton: FC<NextLinkButtonProps> = (props) => {
  return <Button as={OriginalLink} {...props} />
}

export interface NextLinkIconButtonProps
  extends Omit<Merge<OriginalLinkProps, IconButtonProps>, "as" | "ref">,
    HTMLRefAttributes<"a"> {}

export const NextLinkIconButton: FC<NextLinkIconButtonProps> = (props) => {
  return <IconButton as={OriginalLink} {...props} />
}

Image

"use client"

import { styled } from "@yamada-ui/react"
import Image from "next/image"

export const AppImage = styled(Image, {
  forwardProps: ["fill", "height", "width"],
})
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd
2nd