言語を切り替える
テーマを切り替える

shadcn/ui トラブルシューティング:スタイル競合、コンポーネント非表示、TypeScriptエラー

深夜2時、画面上のボタンコンポーネントを見つめています——美しい青いボタンになるべきですが、今は角丸もない普通の HTML button のように見えています。

shadcn/uiのスタイル問題に遭遇するのはこれが初めてではありません。正直に言えば、過去3ヶ月で、書いたコードよりも多くの落とし穴に足を踏み入れてきました。スタイルの競合、コンポーネントが表示されない、TypeScriptのエラー——これらの問題は shadcn/ui の「名物」のように感じられ、新しいプロジェクトでは必ずいくつか遭遇します。

今日は、これらの一般的な問題と解決策を整理し、同じような回り道を避ける手助けをしたいと思います。


スタイル競合のトラブルシューティング

スタイル競合は最も一般的な問題で、全体の約40%を占めています。主な原因はいくつかあります:

CSS変数の競合

shadcn/ui は CSS変数を使ってテーマカラーを管理しています。これらの変数は globals.css で定義されています:

:root {
  --background: 0 0% 100%;
  --foreground: 222.2 84% 4.9%;
  --primary: 222.2 47.4% 11.2%;
  --primary-foreground: 210 40% 2%;
}

ここで問題が発生します。プロジェクトが既に独自のテーマ設定を持っている場合、または shadcn/ui をインストールする前に Tailwind の色設定を変更していた場合、これら2つの設定が競合する可能性があります。

どうデバッグするか?

まず、globals.css を開いて、CSS変数がすべて存在するか確認します。次に、tailwind.config.js の colors 設定を確認します:

module.exports = {
  theme: {
    extend: {
      colors: {
        border: "hsl(var(--border))",
        input: "hsl(var(--input))",
        ring: "hsl(var(--ring))",
        background: "hsl(var(--background))",
        foreground: "hsl(var(--foreground))",
        primary: {
          DEFAULT: "hsl(var(--primary))",
          foreground: "hsl(var(--primary-foreground))",
        },
      },
    },
  },
}

これら2つは対応している必要があります。どの変数が欠けていると、対応するスタイルが機能しません。

私の経験:shadcn/ui をインストールする前に、tailwind.config.jsglobals.css をバックアップしてください。インストール後、2つのファイルの違いを比較し、上書きされた設定を手動で復元します。

Shadow DOM と Tailwind の競合

これは興味深い問題です。Shadow DOM はスタイル隔離のために使用されますが、Tailwind のクラス名は Shadow DOM の境界を越えられません。

最も典型的なシナリオは Dialog コンポーネントです。DialogContent は Portal を使って document.body にレンダリングされ、Shadow DOM の範囲外に出ます——すべてのスタイルが失われます。

2つの解決策

第一に、Shadow DOM を使用しない:

const MyDialogWC = r2wc(MyDialog, {
  shadow: null  // Shadow DOM をオフにする
});

これにより、Portal は正常に動作しますが、スタイル隔離はなくなります。グローバルスタイルを手動で管理し、クラス名の競合に注意する必要があります。

第二に、Safelist を使ってクラス名を強制包含:

// tailwind.config.js
module.exports = {
  safelist: [
    'bg-primary',
    'text-primary-foreground',
    'hover:bg-primary/90',
    'bg-red-500',
    'h-9',
    'h-10',
    'px-3',
    'px-4',
  ],
}

この方法でスタイル生成を保証できますが、Safelist は CSSファイルサイズを増加させます。 trade-off を検討する必要があります。

他の UI ライブラリとの共存

プロジェクトが既に MUI(Material-UI)を使用しており、shadcn/ui に移行したい場合、スタイル競合に遭遇します。

根本原因は Tailwind の Preflight——すべてのブラウザデフォルトスタイルをリセットします。MUI のスタイルもリセットされ、コンポーネントが異常に表示されます。

一般的な試み

Preflight を無効化する人もあります:

module.exports = {
  corePlugins: {
    preflight: false,  // Preflight を無効化
  },
}

しかし、これには副作用があります:Tailwind のスタイルも影響を受けます。一部のコンポーネントが正常に表示されない可能性があります。

より良いアプローチ

Tailwind の prefix 機能を使って、すべての Tailwind クラスにプレフィックスを追加:

module.exports = {
  prefix: 'tw-',  // すべてのクラスが tw-bg-blue-500 になる
}

これにより、Tailwind クラスと MUI クラスが競合しなくなります。ただし、各クラス名の前に手動で tw- を追加する必要があり、少し手間がかかります。

私のアドバイス:プロジェクトに多くの MUI コンポーネントがある場合、すべてを一度に移行するのは避けましょう。まず prefix アプローチで共存し、新しいコンポーネントは shadcn/ui を使用、古いコンポーネントは MUI を維持し、徐々に移行します。

Tailwind 設定の上書き

この落とし穴に何度も足を踏み入れました。

npx shadcn-ui@latest init を実行後、Tailwind 設定ファイルが上書きされます。特に plugins 配列——前に @tailwindcss/forms または他のプラグインを設定していた場合、それらが消えてしまいます。

症状は明らか:フォーム入力のスタイルが突然奇妙になり、一部のコンポーネントがスタイルを全く表示しない。

デバッグ手順

  1. インストール前の tailwind.config.js バックアップを開く
  2. インストール後の設定ファイルと比較
  3. 失ったプラグインを復元:
module.exports = {
  // ... 他の設定
  plugins: [
    require("@tailwindcss/forms"),  // これを復元
    require("tailwindcss-animate"),
  ],
}

予防策:shadcn/ui をインストールする前に、設定ファイルをバックアップしてください。または、専用の設定管理スクリプトを使って、すべてのプラグインを記録します。


コンポーネント非表示のトラブルシューティング

スタイルは問題ないが、コンポーネントが全く表示されない?これはかなり一般的です。

Content パス設定エラー

Tailwind はどのファイルでクラス名が使用されているか知る必要があり、対応する CSS を生成できます。この設定は tailwind.config.jscontent フィールドにあります。

問題は通常:shadcn/ui のコンポーネントディレクトリが含まれていない。

設定を確認

module.exports = {
  content: [
    './src/app/**/*.{ts,tsx}',
    './src/components/**/*.{ts,tsx}',  // これは必須
    './app/**/*.{ts,tsx}',
    './pages/**/*.{ts,tsx}',
  ],
}

コンポーネントを node_modules 内の UI ライブラリに配置する場合、追加が必要:

content: [
  // ... 他のパス
  './node_modules/@your-ui-lib/**/*.{ts,tsx}',
]

私の経験:新しいコンポーネントディレクトリを作成するたびに、content 設定にパスを追加してください。そうしないと、Tailwind がこれらのファイルをスキャンせず、クラス名が生成されません。

globals.css パス問題

shadcn/ui はテーマ変数を定義する CSS ファイルが必要です。このファイルのパスは components.json で設定されます。

問題は通常:パスが間違っている、または複数の globals.css ファイルがある。

デバッグ方法

まず components.json を確認:

{
  "style": "default",
  "css": "src/app/globals.css",  // このパス
}

次に確認:

  1. このファイルは実際に存在するか?
  2. プロジェクトに globals.css は1つだけか?
  3. globals.css は正しくメインファイルにインポートされているか?

複数の globals.css がある場合、余分なものを削除し、1つだけ保持します。

インポート確認

Next.js プロジェクトで、globals.css は app/layout.tsx または pages/_app.tsx でインポートすべき:

import '@/app/globals.css'  // または './globals.css'

インポートされていないと、CSS変数が機能せず、コンポーネントスタイルが完全に失われます。

CSS変数が未定義

globals.css ファイルは存在するが、変数が定義されていない場合もあります。

最も典型的なケースはダークモードです。ダークモードに切り替えて、コンポーネントの色が正しくない——ダークモードの CSS変数が設定されていない可能性があります。

globals.css を確認

:root {
  --background: 0 0% 100%;
  --foreground: 222.2 84% 4.9%;
}

.dark {
  --background: 222.2 84% 4.9%;
  --foreground: 210 40% 2%;
}

.dark クラス下の変数は必須です。定義されていないと、ダークモードのコンポーネントにスタイルがありません。

Tailwind v4 の特殊ケース

Tailwind v4 を使用する場合、設定方法が異なります:

@theme inline {
  --color-background: var(--background);
  --color-foreground: var(--foreground);
  --color-primary: var(--primary);
}

この @theme inline マッピングは必須です。ないと、Tailwind v4 はこれらの変数を認識しません。

インポートパスの大文字小文字問題

この落とし穴に2回足を踏み入れました。

Windows ではファイル名の大文字小文字が区別されませんが、Linux/Mac では区別されます。ローカル開発は問題ないが、プロダクション環境にデプロイするとエラーになります。

症状は通常:コンポーネントはローカルでレンダリングされるが、サーバーにプッシュ後、モジュールが見つからないエラーが表示される。

典型的なエラー

// ❌ 間違い:Button 大文字 B
import { Button } from "@/components/ui/Button"

// ✅ 正しい:button 小文字 b
import { Button } from "@/components/ui/button"

shadcn/ui のコンポーネントファイル名はすべて小文字です。インポートパスは小文字を使用すべきです。

デバッグ方法

すべてのコンポーネントインポート文を確認し、パスが実際のファイル名と一致するか確認します。特にプロダクション環境のエラーメッセージを確認してください。


TypeScript型エラーのトラブルシューティング

TypeScriptエラーは比較的少ないですが、遭遇するとかなり厄介です。

Variant プロパティ型エラー

shadcn/ui の Button コンポーネントには variant プロパティがあり、ボタンスタイル(default、destructive、outline など)を切り替えます。

エラーメッセージは通常:

Type '{ variant: string }' is not assignable to type 'IntrinsicAttributes & ButtonProps'.
Property 'variant' does not exist on type 'IntrinsicAttributes & ButtonProps'.

根本原因

Button コンポーネントの型定義で、variant プロパティが正しくエクスポートされていない。

デバッグ方法

components/ui/button.tsx を開いて、variant の型定義を確認:

const buttonVariants = cva(
  "inline-flex items-center justify-center rounded-md text-sm font-medium",
  {
    variants: {
      variant: {
        default: "bg-primary text-primary-foreground hover:bg-primary/90",
        destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
        outline: "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
      },
    },
  }
)

interface ButtonProps
  extends React.ButtonHTMLAttributes<HTMLButtonElement>,
    VariantProps<typeof buttonVariants> {
  // VariantProps は必須
}

VariantProps<typeof buttonVariants> が欠けていると、variant プロパティの型がなくなります。

私の経験:このエラーに遭遇したら、まずコンポーネントの型定義を確認します。VariantProps が正しく継承されているか確認してください。

React バージョンの互換性

React 19 を使用しているが、一部の依存関係がまだ React 19 をサポートしていない場合、型エラーに遭遇します。

エラーメッセージは通常:

npm error ERESOLVE unable to resolve dependency tree
npm error Found: [email protected]

2つの解決策

第一に、強制インストール:

npm install --legacy-peer-deps
# または
npm install --force

これは peer dependency のバージョン要件を無視します。しかし、互換性問題がある可能性があります。

第二に、React をダウングレード:

npm install react@18 react-dom@18

React 18 を使用し、依存関係が更新された後にアップグレードします。

私のアドバイス:新しいプロジェクトは React 18 がより安定です。shadcn/ui と他の依存関係がすべて React 19 をサポートした後に、アップグレードを考慮してください。

React Hook Form 型問題

shadcn/ui の Form コンポーネントを React Hook Form と Zod と一緒に使用する場合、型マッピング問題に遭遇します。

エラーメッセージは通常:

Type 'info.${number}.fileName' is not assignable to type '"info" | "info.0" | "info.0.fileName"'

これは動的フォームフィールドの型問題です。Zod Schema の型が FormField の name プロパティ型と一致しない。

解決策

Schema 型が正しく推論されているか確認:

const formSchema = z.object({
  email: z.string().email(),
  password: z.string(),
})

type FormValues = z.infer<typeof formSchema>  // この型推論は必須

const form = useForm<FormValues>({
  resolver: zodResolver(formSchema),
})

FormField の name プロパティは自動的に Schema のフィールド名と一致します。

私の経験:動的フォーム(useFieldArray を使用するものなど)の型はより複雑です。Zod Schema の定義と TypeScript の型推論を注意深く確認する必要があります。

型依存関係の不足

TypeScriptエラーは @types/react または @types/react-dom がインストールされていないことが原因の場合もあります。

エラーメッセージは:

Could not find a declaration file for module 'react'

解決策

npm install -D @types/react @types/react-dom

インストール後、TypeScript サーバーを再起動(VSCode で Ctrl+Shift+P を使い、“TypeScript: Restart TS Server” を入力)。

予防策:新しいプロジェクトの開始時に型依存関係をインストールしてください。エラーが表示されてから発見するのを避けます。


ベストプラクティスと予防策

多くの落とし穴に足を踏み入れた後、いくつかの予防策をまとめました。

設定管理の基準

設定ファイルのバックアップ

shadcn/ui をインストールまたは Tailwind 設定を変更する前に、まずバックアップ:

cp tailwind.config.js tailwind.config.js.backup
cp globals.css globals.css.backup

インストール後、違いを比較し、設定を手動でマージします。

単一設定ファイル

1つのプロジェクトは1つの tailwind.config.js と1つの globals.css を使用します。複数の設定ファイルを作成しない——競合しやすいです。

完全なパス設定

content 設定はすべてのコンポーネントディレクトリを含む必要があります:

content: [
  './src/**/*.{ts,tsx}',        // ワイルドカードを使って、すべてのディレクトリをカバー
  './app/**/*.{ts,tsx}',
  './pages/**/*.{ts,tsx}',
  './components/**/*.{ts,tsx}',
]

依存バージョン管理

peerDependencies の確認

新しい依存関係をインストールする前に、peerDependencies を確認:

npm info <package> peerDependencies

依存関係が React 18 を要求するが、プロジェクトが React 19 を使用する場合、互換性を考慮する必要があります。

型依存関係の定期更新

npm update @types/react @types/react-dom

型宣言を React バージョンと同期させます。

テスト戦略

インストール後即座にテスト

shadcn/ui インストール完了後、すぐにスタイルをテスト:

  1. いくつかの shadcn/ui コンポーネントを使って、シンプルなページを作成
  2. スタイルが正常に表示されるか確認
  3. ダークモード切り替えをテスト
  4. TypeScript コンパイルチェックを実行

プロダクション環境テスト

ローカル開発が問題ないことは、プロダクション環境も問題ないことを意味しません:

npm run build
npm run preview

ビルド後プレビューし、スタイルと型が正常か確認します。


まとめ

これほど多くを話しましたが、shadcn/ui の一般的な問題は主に3つの領域に集中しています:

  1. スタイル競合:設定ファイルの上書き、CSS変数の競合、他の UI ライブラリとの共存問題
  2. コンポーネント非表示:content パス設定エラー、globals.css パス問題、インポートパスの大文字小文字区別
  3. TypeScript型エラー:variant プロパティ型の不足、React バージョンの互換性、型依存関係の不足

問題に遭遇したら、この順序でデバッグ:

  1. まず設定ファイルを確認(tailwind.config.js、globals.css)
  2. 次にパス設定を確認(content、インポートパス)
  3. 最後に型定義を確認(コンポーネント型、依存バージョン)

shadcn/ui を使い始める場合、まず空白のプロジェクトで全プロセスを試すことをお勧めします。設定と一般的な問題に慣れた後、実際のプロジェクトで使用します。

shadcn/ui は非常に使いやすいですが、設定は確かに少し複雑です。これらのデバッグ方法を習得すれば、問題に遭遇しても慌てなくなります。

FAQ

shadcn/ui インストール後、スタイルがすべて失われたのはなぜ?
最も一般的な原因は Tailwind 設定の上書きです。確認:

• tailwind.config.js の plugins 配列が完全かどうか
• globals.css のパスが正しいかどうか
• CSS変数がすべて定義されているかどうか

解決策:インストール前に設定ファイルをバックアップ、インストール後、違いを比較し、失った設定を手動で復元します。
ダークモード切り替え後、コンポーネントスタイルが正しくないのはなぜ?
globals.css の .dark クラス下の CSS変数が完全に定義されているか確認:

• .dark クラスが存在する必要がある
• すべてのテーマ変数を再定義する必要がある
• Tailwind v4 は @theme inline で変数をマッピングする必要がある
shadcn/ui は MUI と共存できる?
共存できますが、Tailwind prefix の設定が必要:

• prefix: 'tw-' を設定して、すべての Tailwind クラスにプレフィックスを追加
• 新しいコンポーネントは shadcn/ui を使用、古いコンポーネントは MUI を維持
• 徐々に移行し、一度にすべて変更しない

Preflight を無効化することはお勧めしません。Tailwind のスタイルに影響します。
Button の variant プロパティが TypeScript エラーを表示する場合どうする?
Button コンポーネントの型定義を確認:

• VariantProps<typeof buttonVariants> が継承されている必要がある
• コンポーネントファイルが完全に型をエクスポートしているか確認
• @types/react と @types/react-dom をインストール

型定義が不足している場合、npx shadcn@latest add button でコンポーネントを再インストールします。
React 19 で shadcn/ui を使える?
使えますが、互換性を処理する必要があります:

• インストール時に --legacy-peer-deps または --force を使用
• または package.json の overrides で react-is バージョンを指定
• 新しいプロジェクトはまず React 18 を使用し、依存関係が更新された後にアップグレード
コンポーネントはローカルで正常、プロダクション環境でモジュール見つからないエラー?
通常インポートパスの大文字小文字問題:

• shadcn/ui コンポーネントファイル名はすべて小文字(button.tsx)
• インポートパスはファイル名と一致する必要がある(@/components/ui/button)
• Windows は区別しない、Linux/Mac は区別する——ローカルテストは問題ないがプロダクションでエラー

すべてのインポート文を確認し、パスが完全に一致するか確認します。

5 min read · 公開日: 2026年4月2日 · 更新日: 2026年4月5日

コメント

GitHubアカウントでログインしてコメントできます

関連記事