Next.js (Pages)

Next.jsのpagesディレクトリにYamada UIをインストールして使用するためのガイド。

インストール

  • 1

    アプリケーションを作成する

    Next.jsのアプリケーションを作成します。

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

    セットアップする

    コマンドを実行すると、プロジェクトに必要なファイルやフォルダが作成されます。

    pnpm dlx @yamada-ui/cli init
    
  • 3

    パッケージをインストールする

    アプリケーションに@workspaces/uiをインストールします。

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

    プロバイダーを追加する

    インストール後、アプリケーションのルートにUIProviderを追加します。

    _app.tsx

    import { UIProvider } from "@workspaces/ui"
    import type { AppProps } from "next/app"
    
    export default function App({ Component, pageProps }: AppProps) {
      return (
        <UIProvider>
          <Component {...pageProps} />
        </UIProvider>
      )
    }
    
  • 5

    コンポーネントを使用する

    UIProviderを追加したら、アプリケーション内でコンポーネントを使用します。

    index.tsx

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

    これで、Yamada UIのセットアップは完了です!

スクリプト

ColorModeScript

カラーモードを使用する場合は、正常に動作させるためにbodyColorModeScriptを追加する必要があります。

理由は、カラーモードがlocalStoragecookiesを用いて実装されており、ページの読み込み時に同期を正しく機能させるためです。

  • 1

    スクリプトを追加する

    _document.tsx

    import { Html, Head, Main, NextScript } from "next/document"
    import { ColorModeScript } from "@workspaces/ui"
    
    export default function Document() {
      return (
        <Html lang="en">
          <Head />
          <body>
            <ColorModeScript type="cookie" />
    
            <Main />
            <NextScript />
          </body>
        </Html>
      )
    }
    

    もし、コンフィグdefaultColorModeを変更した場合は、ColorModeScriptdefaultValueを設定します。

    _document.tsx

    import { Html, Head, Main, NextScript } from "next/document"
    import { ColorModeScript } from "@workspaces/ui"
    import { config } from "@workspace/theme"
    
    export default function Document() {
      return (
        <Html lang="en">
          <Head />
          <body>
            <ColorModeScript type="cookie" defaultValue={config.defaultColorMode} />
    
            <Main />
            <NextScript />
          </body>
        </Html>
      )
    }
    
  • 2

    getServerSidePropsを追加する

    複数のページでgetServerSidePropsを共通化するために、getServerSideSharedPropsを定義します。

    get-server-side-props.ts

    import { GetServerSidePropsContext } from "next"
    
    export const getServerSideSharedProps = ({
      req,
    }: GetServerSidePropsContext) => {
      return {
        props: {
          cookies: req.headers.cookie ?? "",
        },
      }
    }
    

    index.tsx

    import { getServerSideSharedProps } from "@/get-server-side-props"
    import { Button } from "@workspaces/ui"
    
    export const getServerSideProps = getServerSideSharedProps
    
    export default function Home() {
      return <Button>Click me!</Button>
    }
    
  • 3

    プロバイダーを更新する

    _app.tsx

    import { UIProvider } from "@workspaces/ui"
    import type { AppProps } from "next/app"
    
    export default function App({ Component, pageProps }: AppProps) {
      const { cookie } = pageProps
    
      return (
        <UIProvider cookie={cookie}>
          <Component {...pageProps} />
        </UIProvider>
      )
    }
    

ThemeSchemeScript

テーマの切り替えを使用する場合は、正常に動作させるためにbodyThemeSchemeScriptを追加する必要があります。

理由は、テーマの切り替えがlocalStoragecookiesを用いて実装されており、ページの読み込み時に同期を正しく機能させるためです。

  • 1

    スクリプトを追加する

    _document.tsx

    import { Html, Head, Main, NextScript } from "next/document"
    import { ThemeSchemeScript } from "@workspaces/ui"
    
    export default function Document() {
      return (
        <Html lang="en">
          <Head />
          <body>
            <ThemeSchemeScript type="cookie" />
    
            <Main />
            <NextScript />
          </body>
        </Html>
      )
    }
    

    もし、コンフィグdefaultThemeSchemeを変更した場合は、ThemeSchemeScriptdefaultValueを設定します。

    _document.tsx

    import { Html, Head, Main, NextScript } from "next/document"
    import { ThemeSchemeScript } from "@workspaces/ui"
    import { config } from "@workspace/theme"
    
    export default function Document() {
      return (
        <Html lang="en">
          <Head />
          <body>
            <ThemeSchemeScript
              type="cookie"
              defaultValue={config.defaultColorMode}
            />
    
            <Main />
            <NextScript />
          </body>
        </Html>
      )
    }
    
  • 2

    getServerSidePropsを追加する

    複数のページでgetServerSidePropsを共通化するために、getServerSideSharedPropsを定義します。

    get-server-side-props.ts

    import { GetServerSidePropsContext } from "next"
    
    export const getServerSideSharedProps = ({
      req,
    }: GetServerSidePropsContext) => {
      return {
        props: {
          cookies: req.headers.cookie ?? "",
        },
      }
    }
    

    index.tsx

    import { getServerSideSharedProps } from "@/get-server-side-props"
    import { Button } from "@workspaces/ui"
    
    export const getServerSideProps = getServerSideSharedProps
    
    export default function Home() {
      return <Button>Click me!</Button>
    }
    
  • 3

    プロバイダーを更新する

    _app.tsx

    import { UIProvider } from "@workspaces/ui"
    import type { AppProps } from "next/app"
    
    export default function App({ Component, pageProps }: AppProps) {
      const { cookie } = pageProps
    
      return (
        <UIProvider cookie={cookie}>
          <Component {...pageProps} />
        </UIProvider>
      )
    }
    

コンポーネントの統合

Next.jsのLinkImageなどのコンポーネントとYamada UIのコンポーネントを統合することができます。

"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