Communitygithub.com

beavon2010/claude-skills

ビルド済みウェブアプリケーションやReactコンポーネントから、CSSや画像をインライン化した自己完結型の静的HTMLを抽出します。特定のUI状態をキャプチャしたい場合、ページの静的バージョンを共有したい場合、またはStitchアップロード用のアセットを準備したい場合に使用します。ユーザーが単に「HTMLを保存」や「ビューをモック」と依頼した場合でも対応します。

claude-skills とは?

このスキルは、ビルド済みのウェブアプリケーションやReactコンポーネントから、自己完結型の静的HTMLファイルを抽出するためのものです。CSSをインライン化し、画像をbase64データURIとして埋め込むことで、単一ファイルで完結した静的HTMLを生成します。主に、特定のUI状態をキャプチャして共有したり、Stitchなどのプラットフォームにアップロードするためのアセットを準備する際に有用です。このスキルは2つの戦略を提供します。推奨される戦略A(Puppeteerスナップショット)は、ヘッドレスChromeを起動して完全にレンダリングされたDOMをキャプチャし、あらゆるフレームワークで動作します。戦略B(ブラウザサブエージェント)は、ページとの対話(クリック、フォーム入力など)が必要な場合に適しています。また、アプリケーションがローカルで実行できない場合の最終手段として、静的フォールバック(MockPage.jsx)も用意されています。AIエージェント(Claude Code、Cursor、Codexなど)のスキルとして設計されており、開発者が迅速にUIの静的スナップショットを生成するのを支援します。

対応✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/beavon2010/claude-skills/tree/HEAD/.claude/skills/extract-static-html

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

静的HTMLの抽出

任意のウェブアプリケーションから自己完結型の静的HTMLファイルを抽出します。

使用する戦略

先に進む前に、ユーザーに使用する戦略を選択してもらう必要があります。以下の選択肢を明確に提示し、デフォルトとして戦略Aを推奨し、各オプションの簡単なメリット/デメリットの要約を提供して、ユーザーが情報に基づいた決定を下せるようにしてください。

戦略A (Puppeteer)戦略B (ブラウザサブエージェント)
いつ使うかアプリがローカルで動作し、認証がない場合ページと先に対話する必要がある場合(クリック、フォーム入力)
忠実度最高 — 計算済みスタイルが解決済み高 — レンダリングされたDOM
セットアップ不要 — モック不要不要 — モック不要
フレームワーク任意任意
出力ファイルに書き込み — サイズ制限なしエージェントコンテキストで切り詰められる可能性あり

[!WARNING] チェックポイント — ユーザー確認が必要です。 先に進む前に、ユーザーにどちらの戦略を希望するかを必ず尋ねてください。 上記の比較表を提示し、デフォルトとして戦略Aを推奨し、 明示的な承認を待ってください。ユーザーが確認するまで、ご自身で決定したり先に進んだりしないでください。


戦略A: Puppeteerスナップショット (推奨)

ヘッドレスChromeを起動し、完全にレンダリングされたDOMをキャプチャし、すべてのCSSがインライン化され、画像がbase64として埋め込まれた自己完結型のHTMLファイルを生成します。任意のフレームワークで動作します — MockPage.jsxは不要です。

前提条件

  • アプリがローカルで実行されていること(例:npm run dev)
  • Node.jsとpuppeteerが利用可能であること(確認:node -e "require('puppeteer')")

ワークフロー

  1. アプリを起動し、ポート番号をメモします。

    [!WARNING] チェックポイント — ユーザー確認が必要です。 ローカルサーバーを起動した後、スナップショットスクリプトを実行したりブラウザサブエージェントを起動したりする前に、必ず一時停止してユーザーに確認を求めてください。URLとポートをユーザーに報告し、アプリが実行中で正しくレンダリングされていることを確認できるようにします。ユーザーが確認するまで、スナップショットのステップに進まないでください。

  2. スナップショットスクリプトを実行:

    npx tsx <SKILL_DIR>/scripts/snapshot.ts \
      --url http://localhost:5173 \
      --output .stitch/home.html \
      --wait 2000
    
  3. 複数ページ — ルートごとに1回実行:

    npx tsx <SKILL_DIR>/scripts/snapshot.ts \
      --url http://localhost:5173 --output .stitch/home.html --wait 2000
    npx tsx <SKILL_DIR>/scripts/snapshot.ts \
      --url http://localhost:5173/pricing --output .stitch/pricing.html --wait 2000
    npx tsx <SKILL_DIR>/scripts/snapshot.ts \
      --url http://localhost:5173/dashboard --output .stitch/dashboard.html --wait 2000 --html-class dark
    
  4. 開発サーバーの後片付け: スナップショット抽出専用にローカル開発サーバーを起動した場合は、抽出が完了したら必ずサーバープロセスを停止するか、バックグラウンドタスクを終了してください。

スクリプトフラグ

フラグデフォルト説明
--url(必須)キャプチャするURL
--output(必須)出力ファイルパス
--wait1000ネットワークアイドル後の追加待機時間(ミリ秒)。遅延読み込みアプリの場合は増やしてください。
--viewport1280x800ビューポートサイズを WIDTHxHEIGHT で指定
--html-class—<html> 要素に追加するクラス(例:dark)
--remove-fixedfalsefixed/sticky要素(Cookieバナー、チャットウィジェット)を削除
--full-heightfalseビューポートをスクロール全体の高さにリサイズ
--title—ページタイトルを上書き(ルートパス、例:/dashboard や /settings/profile に設定)
--auth-script—認証用の async (page) => void 関数をデフォルトエクスポートするJS/TSモジュールへのパス
--inline-canvasfalse<canvas> 要素(ECharts、Chart.js、D3)をbase64の <img> タグに変換

自動的に行われる処理

  • document.styleSheets からすべてのCSSOMルールをキャプチャ(動的なVite/Tailwind開発スタイルとCSS-in-JSを保持)
  • すべての <link rel="stylesheet"> を <style> ブロックにインライン化
  • <img> の src および srcset をbase64データURIに変換(外部フォントはスキップ)
  • 同一オリジンおよび相対パスのアイコンフォントファイル(@font-face)をbase64データURIとしてインライン化し、リガチャがASCIIテキストとしてレンダリングされないようにする
  • <source srcset> URLをbase64としてインライン化
  • 失敗/無効な srcset エントリを削除し、ブラウザがインライン化された src にフォールバックするようにする
  • <script> タグ、Vite HMR開発スタイルブロック(createHotContext、import.meta.hot)、開発オーバーレイを削除
  • インライン化の前に相対的なCSSの url() パスを解決

フレームワーク別の注意点

フレームワーク注意点
React + Viteそのまま動作します。--wait 1000。
Next.jsSSRハイドレーションには --wait 3000。URL: http://localhost:3000。/_next/image からの <img srcset> は自動的にbase64としてインライン化されます。
Angular (@angular/cli / v17+)ng serve でそのまま動作します(デフォルトURL: http://localhost:4200)。Angular Material / PrimeNGのアニメーションハイドレーションと遅延読み込みルートには --wait 2000。
Vue / Nuxtそのまま動作します。
Svelte / SvelteKitそのまま動作します。
StorybookストーリーURLを使用: --url http://localhost:6006/?path=/story/...
SSR (Webpack)より長い --wait が必要になる場合があります。

トラブルシューティング

問題解決策
画像が表示されない--wait を増やす
サーバー停止後に画像が壊れて表示されるsrcset がインライン化されたか確認する — ログで「Inlined N images」を確認。srcset URLが失敗した場合、自動的に削除され src(インライン化済み)が使用されます。
アイコンがテキスト/セリフ体のスタイルなしフォントで表示されるsnapshot.ts が document.styleSheets(ステップ0)からCSSOMをキャプチャし、同一オリジンのアイコンフォント(@font-face)がbase64データURIとしてインライン化されていることを確認。
Next.jsの /_next/image がインライン化されないスナップショット実行時に開発サーバーが実行中であることを確認 — スクリプトは実行中のサーバーから最適化された画像を取得します。
ダークモードが適用されない--html-class dark
出力にCookieバナーがある--remove-fixed
ログインが必要なページ--auth-script ./auth.ts を使用(下記「認証が必要なページ」を参照)
チャート/グラフが空白のボックスになる--inline-canvas を使用して <canvas> をbase64の <img> にシリアライズ
Cannot find module 'puppeteer'npm install -g puppeteer

認証が必要なページ

ログインガード(Vue Routerの beforeEach、Reactの ProtectedRoute など)があるアプリの場合、Puppeteerセッション内で実行される小さな認証スクリプトを作成します:

// auth-myapp.ts
import type { Page } from 'puppeteer';

export default async function authenticate(page: Page) {
  // 例1: ログインフォームに入力して送信
  await page.type('#username', 'admin');
  await page.type('#password', 'password123');
  await page.click('#login-button');
  await page.waitForNavigation({ waitUntil: 'networkidle2' });

  // 例2: Cookie/localStorageを直接注入
  // await page.evaluate(() => {
  //   localStorage.setItem('token', 'mock-jwt-token');
  // });

  // 例3: モジュールインジェクションを介してアプリ独自のログインAPIを呼び出す (Vue/Vite)
  // await page.evaluate(() => {
  //   return new Promise((resolve) => {
  //     const script = document.createElement('script');
  //     script.type = 'module';
  //     script.textContent = `
  //       import { useUserStore } from '/src/store/modules/user.ts';
  //       import { fetchLogin } from '/src/api/auth.ts';
  //       const res = await fetchLogin({ userName: 'Admin', password: '123456' });
  //       useUserStore().setToken(res.token, res.refreshToken);
  //       window.dispatchEvent(new CustomEvent('auth-done'));
  //     `;
  //     document.head.appendChild(script);
  //     window.addEventListener('auth-done', () => resolve(true), { once: true });
  //   });
  // });
}

そして次のように使用します:

npx tsx <SKILL_DIR>/scripts/snapshot.ts \
  --url http://localhost:5173/#/dashboard \
  --output .stitch/dashboard.html \
  --auth-script ./auth-myapp.ts \
  --inline-canvas \
  --wait 5000

スクリプトは最初に --url に移動し(ログインページにリダイレクトされる可能性あり)、認証関数を実行し、認証済みセッションで元の --url に再度移動します。


戦略B: ブラウザサブエージェントによるキャプチャ

キャプチャ前にページと対話する必要がある場合(ボタンのクリック、フォームの入力、タブの移動など)に使用します。ブラウザサブエージェントは完全な制御を提供しますが、大きなページでは出力が切り詰められる可能性があります。

ワークフロー

  1. アプリをローカルで起動します。

  2. ブラウザサブエージェントを使用して移動します。

  3. 必要に応じて対話します(クリック、スクロール、フォーム入力)。

  4. DOMを抽出: document.documentElement.outerHTML

    [!WARNING] 大きなページは切り詰められる可能性があります。これに対処するには:

    • 抽出前に <style> タグを削除: document.querySelectorAll('style').forEach(el => el.remove())
    • スタイルを静的に再追加(Tailwind CDNリンク、ソースCSS)
  5. ファイルに保存します。


付録: 静的フォールバック (MockPage.jsx)

[!NOTE] この方法は最後の手段です。アプリをローカルで実行できない場合(依存関係の破損、バックエンドの欠落、回避不可能な認証壁など)に使用します。Reactコンポーネントを手動で単一のJSXファイルにフラット化する必要があります。可能な限り戦略Aを優先してください。

使用する場合

  • アプリをローカルでまったく実行できない場合
  • モックや回避策なしでは認証が必要なページの場合
  • ナビゲーションでは到達不可能な特定のUI状態(エラー画面、空の状態など)が必要な場合

クイックリファレンス

npx tsx <SKILL_DIR>/scripts/extract_inline_html.ts \
  --index-css src/css/App.css \
  --extra-css index.html \
  --outdir .stitch \
  --page src/MockPage.jsx:Page.html:"Page Title"

主要なフラグ: --no-tailwind(Tailwind以外のアプリ)、--html-class dark(ダークモード)、--css-files(追加のCSSファイル)。

自動検出: Tailwind設定は自動検出されます。@apply ディレクティブは自動的に <style type="text/tailwindcss"> を使用します。

MockPage.jsx ルール

  1. 完全なレイアウトを含める — ヘッダー、サイドバー、フッター(最初に App.js を読む)
  2. すべての条件分岐をフラット化する — 1つの状態を選択し、すべての三項演算子と && ガードを削除する
  3. すべてのデータをハードコードする — {variable} を具体的な値に置き換え、.map() ループを展開する
  4. ロゴを保持する — ローカルパスで <img> を使用する(後処理でインライン化されます)
  5. 浮動要素を削除する — Cookieバナー、チャットウィジェット、フィードバックボタン

後処理

ローカル画像をインライン化:

npx tsx <SKILL_DIR>/scripts/post_process.ts \
  .stitch/Page.html --base-dir <app-directory>

Individual skills in this repo

This repo contains 4 individual skills — each has its own dedicated page.

beavon2010/claude-skills

>- Convert frontend code (Vite, React, Angular, Vue, etc.) to a Stitch Design by chaining static HTML extraction, design system extraction, and file upload. **ALWAYS** use this skill when the user's intent is to move existing web apps or React/Angular/Vue components into Stitch (e.g., requests to "save", "migrate", or "upload"). You must use this skill even for simple "save" operations, as it is the only way to ensure the design system is extracted and assets are properly linked.

beavon2010/claude-skills

Analyze Stitch projects and synthesize a semantic design system into DESIGN.md files

beavon2010/claude-skills

Transforms vague UI ideas into polished, Stitch-optimized prompts. Enhances specificity, adds UI/UX keywords, injects design system context, and structures output for better generation results.

beavon2010/claude-skills

>- Extract a comprehensive design system (DESIGN.md) directly from frontend source code — React, Vue, Svelte, Angular, plain HTML/CSS, or any web framework. Analyzes component files, stylesheets, Tailwind configs, theme definitions, and design tokens to produce a rich, Stitch-compatible design system document. Use this skill whenever the user wants to reverse-engineer a design system from an existing codebase, audit the visual language of a project, extract design tokens from source files, or understand the styling patterns in a frontend repo — even if they just say "what does this app look like?" or "pull out the design from this code.

関連スキル