🔬

WXTでTailwind CSS v4とshadcn/uiを導入する完全ガイド

に公開

はじめに

WXTを使ったChrome拡張機能開発で、Tailwind CSS v4とshadcn/uiを導入する方法を解説します。公式ドキュメントには詳しく書かれていませんが、WXTのexamplesリポジトリに実装例があります。

https://github.com/wxt-dev/examples/tree/main/examples/react-shadcn

Part 1: 基本セットアップ(WXT + Tailwind CSS v4)

1. WXTプロジェクトの作成

pnpm dlx wxt@latest init

# プロンプトで以下を選択
# ✔ Project Directory … wxt-tailwindv4-shadcn
# ✔ Choose a template › react
# ✔ Package Manager › pnpm

cd wxt-tailwindv4-shadcn
pnpm install

2. Tailwind CSS v4のインストール

pnpm add -D tailwindcss @tailwindcss/vite

3. WXTの設定を更新

wxt.config.tsを以下に変更:

import { defineConfig } from "wxt";
import tailwindcss from "@tailwindcss/vite";

export default defineConfig({
  modules: ["@wxt-dev/module-react"],
  vite: () => ({
    plugins: [tailwindcss()],
  }),
});

4. Tailwind CSSファイルの作成

assets/tailwind.cssを新規作成:

@import "tailwindcss";

5. デフォルトのCSSファイルを削除

以下のファイルを削除:

  • entrypoints/popup/App.css
  • entrypoints/popup/style.css

6. Popupの設定

entrypoints/popup/main.tsxを更新:

import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import '@/assets/tailwind.css';

ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
);

entrypoints/popup/App.tsxをTailwind対応版に変更:

function App() {
  return (
    <div className="w-96 p-6">
      <h1 className="text-2xl font-bold text-blue-600 mb-4">
        WXT + Tailwind CSS v4
      </h1>
      <button className="w-full bg-blue-500 hover:bg-blue-600 text-white font-bold py-2 px-4 rounded">
        動作確認
      </button>
    </div>
  );
}

export default App;

動作確認

pnpm dev

Part 2: shadcn/uiの追加

1. パスエイリアスの設定

必要なパッケージをインストール:

pnpm add -D @types/node

wxt.config.tsを更新:

import { defineConfig } from "wxt";
import tailwindcss from "@tailwindcss/vite";
import path from "path";

export default defineConfig({
  modules: ["@wxt-dev/module-react"],
  vite: () => ({
    plugins: [tailwindcss()],
    resolve: {
      alias: {
        "@": path.resolve(__dirname, "./"),
      },
    },
  }),
});

tsconfig.jsonを更新:

{
  "extends": "./.wxt/tsconfig.json",
  "compilerOptions": {
    "allowImportingTsExtensions": true,
    "jsx": "react-jsx",
    "baseUrl": ".",
    "paths": {
      "@/*": ["./*"]
    }
  }
}

2. shadcn/uiの初期化

必要なパッケージをインストール:

pnpm add -D vite @vitejs/plugin-react

vite.config.tsを一時的に作成:

import path from "path";
import react from "@vitejs/plugin-react";
import { defineConfig } from "vite";
import tailwindcss from "@tailwindcss/vite";

export default defineConfig({
  plugins: [react(), tailwindcss()],
  resolve: {
    alias: {
      "@": path.resolve(__dirname, "./"),
    },
  },
});

shadcn/uiを初期化:

pnpm dlx shadcn@latest init

重要: 初期化完了後、vite.config.tsを削除

3. コンポーネントの追加と使用

pnpm dlx shadcn@latest add button card

entrypoints/popup/App.tsxを更新:

import { Button } from '@/components/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';

function App() {
  return (
    <div className="w-[400px]">
      <Card>
        <CardHeader>
          <CardTitle>WXT Extension</CardTitle>
        </CardHeader>
        <CardContent>
          <Button className="w-full">
            shadcn/ui ボタン
          </Button>
        </CardContent>
      </Card>
    </div>
  );
}

export default App;

ハマりポイントと解決策

1. パスエイリアスが解決できない

原因: shadcn/uiとWXTでパス解決の方法が異なる

解決策: tsconfig.jsonとwxt.config.tsの両方に設定を記述

2. vite.config.tsはなぜ一時的?

原因: WXTは内部でViteを管理しており、vite.config.tsがあると競合する

解決策: shadcn CLI実行時のみ存在させ、その後削除

補足: Content ScriptでTailwind CSS/shadcn/uiを使う場合

Content ScriptでもTailwind CSSとshadcn/uiを使いたい場合は、以下の設定が必要です。

Content Scriptの設定

  1. entrypoints/content.tsを削除
  2. entrypoints/contentフォルダを作成
  3. entrypoints/content/style.cssを作成:
@import "tailwindcss";
  1. entrypoints/content/index.tsxを作成:
import './style.css';
import { createRoot } from 'react-dom/client';
import { Button } from '@/components/ui/button';
import { Card, CardContent } from '@/components/ui/card';

function FloatingUI() {
  return (
    <div className="fixed bottom-6 right-6 w-80 z-[999999]">
      <Card className="shadow-2xl">
        <CardContent className="p-4">
          <h3 className="font-bold text-lg mb-3">
            Content Script UI
          </h3>
          <Button className="w-full">
            shadcn/ui ボタン
          </Button>
        </CardContent>
      </Card>
    </div>
  );
}

export default {
  matches: ['<all_urls>'],
  
  main() {
    const container = document.createElement('div');
    container.id = 'my-extension-root';
    document.body.appendChild(container);
    
    const root = createRoot(container);
    root.render(<FloatingUI />);
  },
};

トラブルシューティング

CSSが適用されない場合

  • @/assets/tailwind.cssのimportを確認
  • wxt.config.tsのvite設定を確認

TypeScriptエラーが出る場合

  • tsconfig.jsonのpaths設定を確認
  • @types/nodeがインストールされているか確認

shadcn/uiコンポーネントが動作しない場合

  • components/ui配下にファイルが生成されているか確認
  • パスエイリアスの設定を再確認

まとめ

WXTでTailwind CSS v4とshadcn/uiを導入する方法を解説しました。基本的にはPopupでの使用が主になりますが、Content Scriptでも同様の手法で対応可能です。

この構成により、モダンなUIコンポーネントを使った拡張機能開発が効率的に行えるようになります。

参考

Discussion