building-web-artifacts について
opencodeでフロントエンドのWebアーティファクトを作るスキルです。Reactプロジェクトの初期化から単一HTMLへのバンドルまでを扱い、デザイン、状態管理、アクセシビリティ、検証も案内します。
主な機能
- 01React + TypeScriptプロジェクトの初期化
- 02Parcelによる単一HTMLへのバンドル
- 03デザインとテーマ設定のガイド
- 04コンポーネント状態とアクセシビリティへの対応
- 05パフォーマンスと表示検証のガイド
活用シーン
- 01会話で共有するWebアーティファクトの作成
- 02データ状態を持つフロントエンド画面の構築
- 03アーティファクトのアクセシビリティと表示の確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ osmontero/ opencode-skills --skill building-web-artifactsインストール後、Claude Code で/building-web-artifactsを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
LICENSE.txtscripts/bundle-artifact.shinit-artifact.sh詳細
Web アーティファクトの構築
高機能なフロントエンドの opencode アーティファクトを構築するには、次の手順に従ってください。
scripts/init-artifact.shを使用してフロントエンドのリポジトリを初期化します- 生成されたコードを編集してアーティファクトを開発します
scripts/bundle-artifact.shを使用して、すべてのコードを単一の HTML ファイルにバンドルします- アーティファクトファイルを保存し、その保存場所をユーザーに知らせます
- (任意)アーティファクトをテストします
スタック:React 18 + TypeScript + Vite + Parcel(バンドル)+ Tailwind CSS + shadcn/ui
デザインとスタイルのガイドライン
必須のサブスキル: コンポーネントを記述する前に designing-frontend-interfaces を使用してください。最初にデザインブリーフを作成し、トークンブロックを確定します。shadcn のデフォルトは出発点であって、デザインではありません。変更せずにそのまま使うと、このセクションで警告しているありきたりな出力になります。
出荷前に次のスキルも必須です。状態を網羅するための designing-user-experience と、キーボードおよびスクリーンリーダーのサポートを実現するための building-accessible-interfaces です。
避けるべき、特定の「安っぽい」パターン: すべてを中央揃えの max-w-4xl にする、白地に紫/バイオレットから青へのグラデーションを使う、すべての要素に一律で rounded-lg を使う、あらゆる場所に shadow-md を使う、表示用フォントに Inter や system-ui を使う、本文に text-gray-500 を使う、そしてヒーロー → 3 つの機能カード → CTA という骨組みです。
Tailwind を設定し、デフォルトをそのまま受け入れない
Tailwind のデフォルトは、あくまでデフォルトのパレットです。そのまま使うと、アーティファクトの見た目がどれも同じになってしまいます。ブリーフで定めたトークンブロックを使って上書きしてください。
// tailwind.config.js
export default {
theme: {
extend: {
colors: {
base: "#f7f6f0", surface: "#fffffb", line: "#dcded1",
ink: { DEFAULT: "#1a271a", 2: "#4a5a46", 3: "#79876f" },
accent: { DEFAULT: "#2f6b3c", ink: "#f4fbf5" },
},
fontFamily: {
display: ['"Young Serif"', "Georgia", "serif"],
text: ['"Work Sans"', "system-ui", "sans-serif"],
},
borderRadius: { DEFAULT: "2px" }, // ONE radius
},
},
};
これで bg-base、text-ink-2、border-line、font-display に意味を持たせられ、1 つのファイルでテーマを切り替えられます。applying-themes スキルには、コントラスト検証済みのすぐに使える 10 種類のパレットが用意されています。
また、別の値を使うと決めた場合は、shadcn のデフォルトの radius 変数も無効にしてください。globals.css の --radius は、すべてのコンポーネントに暗黙的に適用されます。
コンポーネントと状態の要件
アーティファクト内のデータ駆動型コンポーネントには、必要な状態をすべて揃える必要があります。状態の一覧は designing-user-experience を参照してください。自己完結型のアーティファクトでは、これらを簡単に見落としがちです。通常、見落としを防ぐ実際のバックエンドがないためです。
if (error) return <ErrorState onRetry={refetch} message={...} />;
if (loading) return <Skeleton />; // matching the real layout
if (!items.length) return query ? <NoResults query={query} onClear={...} />
: <FirstRun onCreate={...} />;
return <List items={items} />;
2 種類の空状態はそれぞれ異なるため、どちらも必要です。生成されたアーティファクトで最もよくある手抜きは、どちらにも No data と表示することです。
アーティファクトのアクセシビリティ
shadcn/ui は Radix を基盤としているため、意図どおりに使えば、そのプリミティブはアクセシブルです。問題は、その周囲に追加するものから生じます。
- アイコンのみのボタンには
aria-labelが必要です。Radix がラベルを推測することはできません - カスタムの
<div onClick>ハンドラーは Radix が提供する機能をすべて迂回します。<Button>を使用してください - フォーカスリングを取り除く
classNameの上書き(代わりのリングを指定せずにfocus:outline-noneを使うなど)は、キーボード操作を妨げます - チャートやキャンバスにはテキストによる代替が必要です。判明した内容を説明するキャプションを付けてください
- テーマ設定後にコントラストを確認してください。Radix は色をチェックしません
パフォーマンス
アーティファクトは自己完結型の単一ファイルなので、バンドルサイズがそのまま全体の読み込み時間になります。
- フォントは base64 の woff2 としてインライン化し、使用する文字に絞り込んでください。 完全な TTF は、バンドルの残りすべてより大きくなる場合があります。
- アイコンライブラリをインポートしないでください。
import { X } from "lucide-react"は、ツリーシェイキングの動作によっては、ライブラリ全体を取り込む可能性があります。個々の SVG を貼り付けてください。 - 約 200 行を超えるリストは仮想化してください。 DOM ノードを何千個も描画すると、タブがフリーズします。
- 大きなリスト内の行には
React.memoを使用し、キーを安定させてください。 - 外部へのリクエストは行わないでください。 アーティファクトは、CDN、リモートフォント、
fetchをブロックする CSP のもとで実行されることがよくあります。すべてインライン化する必要があります。
検証
アーティファクトを提示する前に、bundle.html を開いて確認してください。
python3 -c "
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
b = p.chromium.launch(); pg = b.new_page(viewport={'width':1440,'height':900})
errs=[]; pg.on('console', lambda m: m.type=='error' and errs.append(m.text))
pg.on('pageerror', lambda e: errs.append(str(e)))
pg.goto('file://$PWD/bundle.html'); pg.wait_for_timeout(1200)
pg.screenshot(path='/tmp/artifact.png', full_page=True)
pg.set_viewport_size({'width':390,'height':844})
pg.screenshot(path='/tmp/artifact-mobile.png', full_page=True)
print('CONSOLE ERRORS:', errs); b.close()"
その後、両方のスクリーンショットを確認してください。バンドルのビルドが成功しても、表示が真っ白になることがあります。インライン化されていないアセット、CSP 違反、または遅延描画される分岐の実行時エラーがあると、ビルドは問題なく完了してもページは空白になります。
クイックスタート
ステップ 1:プロジェクトを初期化する
初期化スクリプトを実行して、新しい React プロジェクトを作成します。
bash scripts/init-artifact.sh <project-name>
cd <project-name>
以下が設定済みのプロジェクトが作成されます。
- ✅ React + TypeScript(Vite 経由)
- ✅ テーマシステムとして shadcn/ui を採用した Tailwind CSS 3.4.1
- ✅ パスエイリアス(
@/)を設定済み - ✅ 40 以上の shadcn/ui コンポーネントをプリインストール済み
- ✅ Radix UI の依存関係をすべて含む
- ✅ バンドル用に Parcel を設定済み(.parcelrc 経由)
- ✅ Node 18 以降との互換性(Vite のバージョンを自動検出して固定)
ステップ 2:アーティファクトを開発する
アーティファクトを作成するには、生成されたファイルを編集します。ガイダンスについては、以下の 一般的な開発タスク を参照してください。
ステップ 3:単一の HTML ファイルにバンドルする
React アプリを単一の HTML アーティファクトにバンドルするには、次を実行します。
bash scripts/bundle-artifact.sh
bundle.html が作成されます。これは、すべての JavaScript、CSS、依存関係がインライン化された自己完結型のアーティファクトです。このファイルは、アーティファクトとしてエージェントとの会話で直接共有できます。
要件:プロジェクトのルートディレクトリに index.html が必要です。
スクリプトの処理内容:
- バンドル用の依存関係(parcel、@parcel/config-default、parcel-resolver-tspaths、html-inline)をインストールする
- パスエイリアスをサポートする
.parcelrc設定ファイルを作成する - Parcel でビルドする(ソースマップなし)
- html-inline を使用して、すべてのアセットを単一の HTML にインライン化する
ステップ 4:アーティファクトをユーザーと共有する
最後に、バンドルされた HTML ファイルを会話でユーザーと共有し、アーティファクトとして表示できるようにします。
ステップ 5:アーティファクトのテスト/表示(任意)
注:この手順は完全に任意です。必要な場合、または依頼された場合にのみ実行してください。
アーティファクトのテスト/表示には、利用可能なツール(他の Skills や、Playwright、Puppeteer などの組み込みツールを含む)を使用します。一般に、アーティファクトをあらかじめテストするのは避けてください。完成したアーティファクトを表示するまでに遅延が生じるためです。依頼された場合や問題が発生した場合は、アーティファクトを提示した後にテストしてください。
参考資料
- shadcn/ui コンポーネント:https://ui.shadcn.com/docs/components