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.js と globals.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 または他のプラグインを設定していた場合、それらが消えてしまいます。
症状は明らか:フォーム入力のスタイルが突然奇妙になり、一部のコンポーネントがスタイルを全く表示しない。
デバッグ手順:
- インストール前の
tailwind.config.jsバックアップを開く - インストール後の設定ファイルと比較
- 失ったプラグインを復元:
module.exports = {
// ... 他の設定
plugins: [
require("@tailwindcss/forms"), // これを復元
require("tailwindcss-animate"),
],
}
予防策:shadcn/ui をインストールする前に、設定ファイルをバックアップしてください。または、専用の設定管理スクリプトを使って、すべてのプラグインを記録します。
コンポーネント非表示のトラブルシューティング
スタイルは問題ないが、コンポーネントが全く表示されない?これはかなり一般的です。
Content パス設定エラー
Tailwind はどのファイルでクラス名が使用されているか知る必要があり、対応する CSS を生成できます。この設定は tailwind.config.js の content フィールドにあります。
問題は通常: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", // このパス
}
次に確認:
- このファイルは実際に存在するか?
- プロジェクトに globals.css は1つだけか?
- 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 インストール完了後、すぐにスタイルをテスト:
- いくつかの shadcn/ui コンポーネントを使って、シンプルなページを作成
- スタイルが正常に表示されるか確認
- ダークモード切り替えをテスト
- TypeScript コンパイルチェックを実行
プロダクション環境テスト:
ローカル開発が問題ないことは、プロダクション環境も問題ないことを意味しません:
npm run build
npm run preview
ビルド後プレビューし、スタイルと型が正常か確認します。
まとめ
これほど多くを話しましたが、shadcn/ui の一般的な問題は主に3つの領域に集中しています:
- スタイル競合:設定ファイルの上書き、CSS変数の競合、他の UI ライブラリとの共存問題
- コンポーネント非表示:content パス設定エラー、globals.css パス問題、インポートパスの大文字小文字区別
- TypeScript型エラー:variant プロパティ型の不足、React バージョンの互換性、型依存関係の不足
問題に遭遇したら、この順序でデバッグ:
- まず設定ファイルを確認(tailwind.config.js、globals.css)
- 次にパス設定を確認(content、インポートパス)
- 最後に型定義を確認(コンポーネント型、依存バージョン)
shadcn/ui を使い始める場合、まず空白のプロジェクトで全プロセスを試すことをお勧めします。設定と一般的な問題に慣れた後、実際のプロジェクトで使用します。
shadcn/ui は非常に使いやすいですが、設定は確かに少し複雑です。これらのデバッグ方法を習得すれば、問題に遭遇しても慌てなくなります。
FAQ
shadcn/ui インストール後、スタイルがすべて失われたのはなぜ?
• tailwind.config.js の plugins 配列が完全かどうか
• globals.css のパスが正しいかどうか
• CSS変数がすべて定義されているかどうか
解決策:インストール前に設定ファイルをバックアップ、インストール後、違いを比較し、失った設定を手動で復元します。
ダークモード切り替え後、コンポーネントスタイルが正しくないのはなぜ?
• .dark クラスが存在する必要がある
• すべてのテーマ変数を再定義する必要がある
• Tailwind v4 は @theme inline で変数をマッピングする必要がある
shadcn/ui は MUI と共存できる?
• prefix: 'tw-' を設定して、すべての Tailwind クラスにプレフィックスを追加
• 新しいコンポーネントは shadcn/ui を使用、古いコンポーネントは MUI を維持
• 徐々に移行し、一度にすべて変更しない
Preflight を無効化することはお勧めしません。Tailwind のスタイルに影響します。
Button の variant プロパティが TypeScript エラーを表示する場合どうする?
• 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日
関連記事
n8n ワークフロー構築:ノード接続から自動化シナリオ設計まで
n8n ワークフロー構築:ノード接続から自動化シナリオ設計まで
GitHub Actions 入門:YAMLワークフロー基礎とトリガー設定
GitHub Actions 入門:YAMLワークフロー基礎とトリガー設定
Supabase データベース設計:テーブル構造、リレーションとRLS完全ガイド

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