Tomoki Ota's Blog

article icon

Next.js 15でshadcn/uiを使ってみる

作成日 

はじめに

以前、Qiitaに投稿した巷で噂のshadcn/uiをNext.jsで使ってみたという記事は、多くの方に読んでいただきました。特にこの記事は現在も多くの方にご覧いただいており、大変うれしく思っています。

巷で噂のshadcn/uiをNext.jsで使ってみた - Qiitashadcn/uiとは shadcn/uiとは、これは Radix UIとTailwind CSSを使って書かれた UI コンポーネントをまとめたもので、TailwindCSS を通じてスタイルをカスタマイズできる。2023 JavaScript Rising Stars...
favicon of https://qiita.com/twrcd1227/items/d4a67bb155503fde30f5qiita.com
ogp of https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-user-contents.imgix.net%2Fhttps%253A%252F%252Fcdn.qiita.com%252Fassets%252Fpublic%252Farticle-ogp-background-afbab5eb44e0b055cce1258705637a91.png%3Fixlib%3Drb-4.0.0%26w%3D1200%26blend64%3DaHR0cHM6Ly9xaWl0YS11c2VyLXByb2ZpbGUtaW1hZ2VzLmltZ2l4Lm5ldC9odHRwcyUzQSUyRiUyRnFpaXRhLWltYWdlLXN0b3JlLnMzLmFwLW5vcnRoZWFzdC0xLmFtYXpvbmF3cy5jb20lMkYwJTJGMTU2MDk2JTJGcHJvZmlsZS1pbWFnZXMlMkYxNzIyNzQ4MTE3P2l4bGliPXJiLTQuMC4wJmFyPTElM0ExJmZpdD1jcm9wJm1hc2s9ZWxsaXBzZSZiZz1GRkZGRkYmZm09cG5nMzImcz0yNmM0N2E0Mjk0NTcwMWJlOWU1YjRjMjRjZThhYjc0Zg%26blend-x%3D120%26blend-y%3D467%26blend-w%3D82%26blend-h%3D82%26blend-mode%3Dnormal%26s%3D18a57652c840eb72153a43ed9fb114e1?ixlib=rb-4.0.0&w=1200&fm=jpg&mark64=aHR0cHM6Ly9xaWl0YS11c2VyLWNvbnRlbnRzLmltZ2l4Lm5ldC9-dGV4dD9peGxpYj1yYi00LjAuMCZ3PTk2MCZoPTMyNCZ0eHQ9JUU1JUI3JUI3JUUzJTgxJUE3JUU1JTk5JTgyJUUzJTgxJUFFc2hhZGNuJTJGdWklRTMlODIlOTJOZXh0LmpzJUUzJTgxJUE3JUU0JUJEJUJGJUUzJTgxJUEzJUUzJTgxJUE2JUUzJTgxJUJGJUUzJTgxJTlGJnR4dC1hbGlnbj1sZWZ0JTJDdG9wJnR4dC1jb2xvcj0lMjMxRTIxMjEmdHh0LWZvbnQ9SGlyYWdpbm8lMjBTYW5zJTIwVzYmdHh0LXNpemU9NTYmdHh0LXBhZD0wJnM9OWFlYzA3OGUxNWZhMDYzY2QyOWRlMThiZWUwZmIzMGI&mark-x=120&mark-y=112&blend64=aHR0cHM6Ly9xaWl0YS11c2VyLWNvbnRlbnRzLmltZ2l4Lm5ldC9-dGV4dD9peGxpYj1yYi00LjAuMCZ3PTgzOCZoPTU4JnR4dD0lNDB0d3JjZDEyMjcmdHh0LWNvbG9yPSUyMzFFMjEyMSZ0eHQtZm9udD1IaXJhZ2lubyUyMFNhbnMlMjBXNiZ0eHQtc2l6ZT0zNiZ0eHQtcGFkPTAmcz04MmUyNjAyOGUyYjE3M2E0NGZkZWNjOGUwMDQ3ODMyNw&blend-x=242&blend-y=480&blend-w=838&blend-h=46&blend-fit=crop&blend-crop=left%2Cbottom&blend-mode=normal&s=23445e8f8033dbeca5a1ddfd58de089f

そこで今回は、最新のNext.js 15とReact 19に対応したshadcn/uiの使い方を改めて解説していきたいと思います。これから新しいプロジェクトで採用を検討している方や、既存のプロジェクトでのバージョンアップを検討している方のお役に立てれば幸いです。

shadcn/uiとは?

The Foundation for your Design System - shadcn/uiA set of beautifully designed components that you can customize, extend, and build on. Start here then make it your own. Open Source. Open Code.
favicon of ui.shadcn.com
ogp of https://ui.shadcn.com/og?title=The%20Foundation%20for%20your%20Design%20System&description=A%20set%20of%20beautifully%20designed%20components%20that%20you%20can%20customize%2C%20extend%2C%20and%20build%20on.%20Start%20here%20then%20make%20it%20your%20own.%20Open%20Source.%20Open%20Code.

Qiitaの記事にも書いているのですが、shadcn/uiとはまず何かを紹介したいと思います。shadcn/uiとは、 Radix UITailwind CSSを使って書かれた UI コンポーネントをまとめたもので、Tailwind CSS でスタイルをカスタマイズできます。

shadcn/uiは、柔軟性拡張性 が高く、必要なコンポーネントだけを選択し、自分でカスタマイズすることができます。また、通常のコンポーネントライブラリとは異なり、npmパッケージとして配布されていないので、npmの依存関係に影響しません。また、コンポーネントのコードはCLIでダウンロードすることができます。

環境

この記事では、Next.js 15, React 19で実際にshadcn/uiをインストールしていきます。執筆時点の shadcn/uiのバージョンは2.1.8です。また、記事内では、srcディレクトリ、App RouterでNext.jsを実行しておりますが、Pages Routerやsrcディレクトリを使わない場合、Next.js 15・React 19以前のバージョンでも同じようにインストールは可能です。

インストール

npx shadcn@latest initをターミナルで叩いてインストールします。

$ npx shadcn@latest init
Need to install the following packages:
[email protected]
Ok to proceed? (y) y
? Which style would you like to use?# New YorkかDefaultのどちらのスタイルにするか選択する
   New York
    Default
? Which color would you like to use as the base color?# ベースカラーを以下から選ぶ
   Neutral
    Gray
    Zinc
    Stone
    Slate
? Would you like to use CSS variables for theming? › no / yes
# Next.js 15, React19を使用している場合はさらに以下の質問があります。
? How would you like to proceed? › 以下どちらのオプションを使用してインストールするかを選択する
    Use --force # 依存関係の競合やエラーを無視して強制的にインストールする
   Use --legacy-peer-deps # 互換性を維持しながらインストールする

ちなみに、スタイルについては、 https://ui.shadcn.com/docs/components/accordion でコンポーネントごとに、defaultとNewYorkの例をみることができます。また、テーマについては、https://ui.shadcn.com/themes でプレビューを確認することができます。

初期化が完了すると、components.jsonsrc/lib/utils.ts が作成されます。

src/lib/utils.ts
import { clsx, type ClassValue } from "clsx"
import { twMerge } from "tailwind-merge"
 
export function cn(...inputs: ClassValue[]) {
  return twMerge(clsx(inputs))
}
components.json
{
  "$schema": "https://ui.shadcn.com/schema.json",
  "style": "new-york",
  "rsc": true,
  "tsx": true,
  "tailwind": {
    "config": "tailwind.config.ts",
    "css": "src/app/globals.css",
    "baseColor": "neutral",
    "cssVariables": true,
    "prefix": ""
  },
  "aliases": {
    "components": "@/components",
    "utils": "@/lib/utils",
    "ui": "@/components/ui",
    "lib": "@/lib",
    "hooks": "@/hooks"
  },
  "iconLibrary": "lucide"
}

componentsを導入する

ここではNext.jsで試しに accordion をインストールする。

$ npx shadcn@latest add accordion
? How would you like to proceed? › 以下どちらのオプションを使用してインストールするかを選択する
   Use --force # 依存関係の競合やエラーを無視して強制的にインストールする
    Use --legacy-peer-deps # 互換性を維持しながらインストールする

すると、components/ui/accordion.tsx が作成されます。

accordion.tsx
components/ui/accordion.tsx
"use client"
 
import * as React from "react"
import * as AccordionPrimitive from "@radix-ui/react-accordion"
import { ChevronDown } from "lucide-react"
 
import { cn } from "@/lib/utils"
 
const Accordion = AccordionPrimitive.Root
 
const AccordionItem = React.forwardRef<
  React.ElementRef<typeof AccordionPrimitive.Item>,
  React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Item>
>(({ className, ...props }, ref) => (
  <AccordionPrimitive.Item
    ref={ref}
    className={cn("border-b", className)}
    {...props}
  />
))
AccordionItem.displayName = "AccordionItem"
 
const AccordionTrigger = React.forwardRef<
  React.ElementRef<typeof AccordionPrimitive.Trigger>,
  React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Trigger>
>(({ className, children, ...props }, ref) => (
  <AccordionPrimitive.Header className="flex">
    <AccordionPrimitive.Trigger
      ref={ref}
      className={cn(
        "flex flex-1 items-center justify-between py-4 text-sm font-medium transition-all hover:underline text-left [&[data-state=open]>svg]:rotate-180",
        className
      )}
      {...props}
    >
      {children}
      <ChevronDown className="h-4 w-4 shrink-0 text-muted-foreground transition-transform duration-200" />
    </AccordionPrimitive.Trigger>
  </AccordionPrimitive.Header>
))
AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName
 
const AccordionContent = React.forwardRef<
  React.ElementRef<typeof AccordionPrimitive.Content>,
  React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Content>
>(({ className, children, ...props }, ref) => (
  <AccordionPrimitive.Content
    ref={ref}
    className="overflow-hidden text-sm data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down"
    {...props}
  >
    <div className={cn("pb-4 pt-0", className)}>{children}</div>
  </AccordionPrimitive.Content>
))
AccordionContent.displayName = AccordionPrimitive.Content.displayName
 
export { Accordion, AccordionItem, AccordionTrigger, AccordionContent }

インストールしたAccordionを以下のようにpage.tsxからインポートします。

src/app/sample/page.tsx
import {
  Accordion,
  AccordionContent,
  AccordionItem,
  AccordionTrigger,
} from "@/components/ui/accordion";
 
export default function Page() {
  return (
    <Accordion type="single" collapsible>
      <AccordionItem value="item-1">
        <AccordionTrigger>ここをクリック!</AccordionTrigger>
        <AccordionContent>Hello!</AccordionContent>
      </AccordionItem>
    </Accordion>
  );
}

npm run devして、https://localhost:3000/sample にアクセスすると以下のように表示されます。

alt text

そのほかのコンポーネントも同様にインストール可能です。どのようなコンポーネントが存在するかは https://ui.shadcn.com/docs/components/accordion に詳細が全て載っています。

chartを導入する

Rechartという機能を使って、さまざまなグラフを簡単に導入することができます。どのようなグラフがあるかは、 https://ui.shadcn.com/charts で確認することができます。

chartを導入する場合は、package.jsonを以下を追記します。

package.json
"overrides": {
  "react-is": "^19.0.0"
}

npm install --legacy-peer-depsをして、あとは上記のcomponentsを導入する と同じくnpx shadcn@latest add chartをターミナルで叩けば使用可能です。

終わりに

他にもFigmaとの連携やCSS変数やユーティリティクラスの使い方、ダークテーマの使い方について知りたい方は、Qiitaの記事の巷で噂のshadcn/uiをNext.jsで使ってみたを参考にしてみてください。

巷で噂のshadcn/uiをNext.jsで使ってみた - Qiitashadcn/uiとは shadcn/uiとは、これは Radix UIとTailwind CSSを使って書かれた UI コンポーネントをまとめたもので、TailwindCSS を通じてスタイルをカスタマイズできる。2023 JavaScript Rising Stars...
favicon of https://qiita.com/twrcd1227/items/d4a67bb155503fde30f5qiita.com
ogp of https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-user-contents.imgix.net%2Fhttps%253A%252F%252Fcdn.qiita.com%252Fassets%252Fpublic%252Farticle-ogp-background-afbab5eb44e0b055cce1258705637a91.png%3Fixlib%3Drb-4.0.0%26w%3D1200%26blend64%3DaHR0cHM6Ly9xaWl0YS11c2VyLXByb2ZpbGUtaW1hZ2VzLmltZ2l4Lm5ldC9odHRwcyUzQSUyRiUyRnFpaXRhLWltYWdlLXN0b3JlLnMzLmFwLW5vcnRoZWFzdC0xLmFtYXpvbmF3cy5jb20lMkYwJTJGMTU2MDk2JTJGcHJvZmlsZS1pbWFnZXMlMkYxNzIyNzQ4MTE3P2l4bGliPXJiLTQuMC4wJmFyPTElM0ExJmZpdD1jcm9wJm1hc2s9ZWxsaXBzZSZiZz1GRkZGRkYmZm09cG5nMzImcz0yNmM0N2E0Mjk0NTcwMWJlOWU1YjRjMjRjZThhYjc0Zg%26blend-x%3D120%26blend-y%3D467%26blend-w%3D82%26blend-h%3D82%26blend-mode%3Dnormal%26s%3D18a57652c840eb72153a43ed9fb114e1?ixlib=rb-4.0.0&w=1200&fm=jpg&mark64=aHR0cHM6Ly9xaWl0YS11c2VyLWNvbnRlbnRzLmltZ2l4Lm5ldC9-dGV4dD9peGxpYj1yYi00LjAuMCZ3PTk2MCZoPTMyNCZ0eHQ9JUU1JUI3JUI3JUUzJTgxJUE3JUU1JTk5JTgyJUUzJTgxJUFFc2hhZGNuJTJGdWklRTMlODIlOTJOZXh0LmpzJUUzJTgxJUE3JUU0JUJEJUJGJUUzJTgxJUEzJUUzJTgxJUE2JUUzJTgxJUJGJUUzJTgxJTlGJnR4dC1hbGlnbj1sZWZ0JTJDdG9wJnR4dC1jb2xvcj0lMjMxRTIxMjEmdHh0LWZvbnQ9SGlyYWdpbm8lMjBTYW5zJTIwVzYmdHh0LXNpemU9NTYmdHh0LXBhZD0wJnM9OWFlYzA3OGUxNWZhMDYzY2QyOWRlMThiZWUwZmIzMGI&mark-x=120&mark-y=112&blend64=aHR0cHM6Ly9xaWl0YS11c2VyLWNvbnRlbnRzLmltZ2l4Lm5ldC9-dGV4dD9peGxpYj1yYi00LjAuMCZ3PTgzOCZoPTU4JnR4dD0lNDB0d3JjZDEyMjcmdHh0LWNvbG9yPSUyMzFFMjEyMSZ0eHQtZm9udD1IaXJhZ2lubyUyMFNhbnMlMjBXNiZ0eHQtc2l6ZT0zNiZ0eHQtcGFkPTAmcz04MmUyNjAyOGUyYjE3M2E0NGZkZWNjOGUwMDQ3ODMyNw&blend-x=242&blend-y=480&blend-w=838&blend-h=46&blend-fit=crop&blend-crop=left%2Cbottom&blend-mode=normal&s=23445e8f8033dbeca5a1ddfd58de089f
この記事をシェアするx icon
アイコン画像
Tomoki Ota

フルスタックエンジニア。Goが好き。趣味はカメラと旅行です📷