screenshots について
screenshotsは、マーケティング、ソーシャルメディア、ランディングページ、ドキュメント向けにPlaywrightでアプリのスクリーンショットを撮るスキルです。URLや要件の確認、アプリの調査、HiDPI画像の生成を案内します。
主な機能
- 01Playwrightでの撮影手順
- 022倍HiDPIキャプチャ
- 03URLと撮影要件の確認
- 04コードベースとルートの調査
- 05撮影時の問題解決ガイド
活用シーン
- 01Product Hunt用のアプリ画像作成
- 02ソーシャルメディア素材の制作
- 03ランディングページの撮影
- 04アプリ画面のドキュメント化
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ sickn33/ agentic-awesome-skills --skill screenshotsインストール後、Claude Code で/screenshotsを入力して読み込まれたか確認します。
詳細
スクリーンショット
Playwrightを直接使用して、アプリのマーケティング品質のスクリーンショットを生成します。deviceScaleFactor: 2 を使用し、真のHiDPI(2倍のRetina)解像度でキャプチャします。
このスキルを使う場面
次の場合にこのスキルを使います。
- ユーザーがProduct Hunt向けのスクリーンショットを作成したい場合
- ソーシャルメディア向けのスクリーンショットを作成する場合
- ランディングページ用の画像を生成する場合
- ドキュメント用のスクリーンショットを作成する場合
- ユーザーがマーケティング品質のアプリのスクリーンショットを求めている場合
前提条件
Playwrightが利用可能である必要があります。次のコマンドで確認します。
npm ls playwright @playwright/test --depth=0
見つからない場合は、ユーザーに次のように伝えます。
Playwrightが必要です。次のコマンドでインストールしてください:
npm install -D playwrightまたはnpm install -D @playwright/test
ステップ1:アプリのURLを確認する
$1 が指定されている場合は、それをアプリのURLとして使用します。
URLが指定されていない場合:
package.jsonのスクリプトを確認し、開発サーバーが起動していそうか調べますAskUserQuestionを使って、ユーザーにURLを尋ねるか、開発サーバーの起動を手伝うことを提案します
候補として提示する一般的なデフォルトURL:
http://localhost:3000(Next.js、Create React App、Rails)http://localhost:5173(Vite)http://localhost:4000(Phoenix)http://localhost:8080(Vue CLI、汎用)
ステップ2:要件を確認する
次の質問を AskUserQuestion で尋ねます。
質問1:スクリーンショットの枚数
- ヘッダー:「枚数」
- 質問:「スクリーンショットは何枚必要ですか?」
- 選択肢:
- 「3-5」- 主要機能を手早く紹介
- 「5-10」- 機能を網羅的に紹介
- 「10+」- マーケティング素材一式
質問2:用途
- ヘッダー:「用途」
- 質問:「これらのスクリーンショットは何に使用しますか?」
- 選択肢:
- 「Product Hunt」- ヒーロー画像と機能の紹介
- 「ソーシャルメディア」- 目を引く機能のデモ
- 「ランディングページ」- マーケティング用セクションとメリット
- 「ドキュメント」- UIのリファレンスとチュートリアル
質問3:認証
- ヘッダー:「認証」
- 質問:「スクリーンショットを撮りたい機能にアクセスするには、アプリへのログインが必要ですか?」
- 選択肢:
- 「ログイン不要」- 公開ページのみ
- 「はい、認証情報を提供します」- 先にログインが必要
ユーザーが「はい、認証情報を提供します」を選んだ場合は、追加で次の質問をします。
- 「ログインページのURLは何ですか?」(例:
/login、/sign-in) - 「メールアドレスまたはユーザー名は何ですか?」
- 既存の認証済みブラウザーセッション、またはプライベート環境/シークレットマネージャーを使用します。チャットでパスワードを尋ねてはいけません。
スクリプトはPlaywrightのスマートロケーターを使用して、ログインフォームのフィールドを自動的に検出します。
ステップ3:コードベースを分析して機能を把握する
アプリを理解し、スクリーンショットに適した箇所を特定するため、コードベースを詳しく調べます。
3.1:まずドキュメントを読む
アプリの機能を理解するため、必ず次のファイルから読み始めます。
-
README.md(およびサブディレクトリ内にあるREADMEファイル)- README全体を読み、次の点を確認します。
- アプリの内容と、解決する課題
- 主な機能とできること
- すでに記載されているスクリーンショットや機能の説明
-
CHANGELOG.md または HISTORY.md - 紹介する価値のある最近の機能
-
docs/ ディレクトリ - 機能に関する追加ドキュメント
3.2: ルートを分析してページを見つける
ルーティング設定を読み取り、利用可能なすべてのページを洗い出します:
| フレームワーク | 読み取るファイル | 探すべきもの |
|---|---|---|
| Next.js App Router | app/ ディレクトリ構造 | page.tsx を含む各フォルダーがルート |
| Next.js Pages Router | pages/ ディレクトリ | 各ファイルがルート |
| Rails | config/routes.rb | すべてのルートを把握するためファイル全体を読む |
| React Router | createBrowserRouter または <Route を検索 | パスを持つルート定義 |
| Vue Router | src/router/index.js または router.js | パス定義を持つルートの配列 |
| SvelteKit | src/routes/ ディレクトリ | +page.svelte を含む各フォルダーがルート |
| Remix | app/routes/ ディレクトリ | ファイルベースのルーティング |
| Laravel | routes/web.php | ルート定義 |
| Django | urls.py ファイル | URL パターン |
| Express | app.get、router.get を検索 | ルートハンドラー |
重要: これらのファイルが存在するかを確認するだけでなく、実際に読み取ってください。ルート定義は、スクリーンショットに利用できるページを教えてくれます。
3.3: 主要なコンポーネントを特定する
スクリーンショットに適した機能を表すコンポーネントを探します:
- ダッシュボードのコンポーネント
- 独自の UI を持つ機能セクション
- フォームとインタラクティブな入力
- データの可視化 (チャート、グラフ、テーブル)
- モーダルとダイアログ
- ナビゲーションとサイドバー
- 設定パネル
- ユーザープロフィールのセクション
3.4: マーケティング素材を確認する
主要な機能をほのめかす既存のマーケティングコンテンツを探します:
- ランディングページのコンポーネント (多くの場合
components/landing/またはcomponents/marketing/) - 機能一覧のコンポーネント
- 料金表
- お客様の声のセクション
3.5: 機能一覧を作成する
発見した機能を次の項目とともに網羅的にリストアップします:
- 機能名 (README またはコンポーネント名から)
- URL パス (ルートから)
- フォーカスする CSS セレクター (コンポーネント構造から)
- 必要な UI の状態 (ログイン済み、データ投入済み、モーダルを開いた状態、特定のタブを選択した状態)
Step 4: ユーザーとスクリーンショットを計画する
発見した機能をユーザーに提示し、リストの確認または修正を依頼します。
AskUserQuestion を使用します:
- Header: "Features"
- Question: "I found these features in your codebase. Which would you like to screenshot?"
- Options: 発見した主要な機能を 3〜4 個リストアップし、さらに「Let me pick specific ones」を加えます
ユーザーが特定のものを希望する場合は、何を正確にキャプチャするのかを明確にするための追加の質問をします。
Step 5: スクリーンショットディレクトリを作成する
mkdir -p screenshots
Step 6: Playwright スクリプトを生成して実行する
適切な HiDPI 設定で Playwright を使用する Node.js スクリプトを作成します。スクリプトは次のようにします:
- 真の retina 解像度のために
deviceScaleFactor: 2を使用する - ビューポートを 1440x900 に設定する (2880x1800 ピクセルの画像を生成します)
- 認証情報が提供された場合は認証を処理する
- 各ページに移動してスクリーンショットをキャプチャする
スクリプトテンプレート
このスクリプトを一時ファイル (例: screenshot-script.mjs) に書き込み、実行します:
import { chromium } from 'playwright';
const BASE_URL = '[APP_URL]';
const SCREENSHOTS_DIR = './screenshots';
// Authentication config (if needed)
const AUTH = {
needed: false, // set true only for an authorized test account
loginUrl: '[LOGIN_URL]',
email: process.env.SCREENSHOT_EMAIL,
password: process.env.SCREENSHOT_PASSWORD,
};
// Screenshots to capture
const SCREENSHOTS = [
{ name: '01-feature-name', url: '/path', waitFor: '[optional-selector]' },
{ name: '02-another-feature', url: '/another-path' },
// ... add all planned screenshots
];
async function main() {
const browser = await chromium.launch();
// Create context with HiDPI settings
const context = await browser.newContext({
viewport: { width: 1440, height: 900 },
deviceScaleFactor: 2, // This is the key for true retina screenshots
});
const page = await context.newPage();
// Handle authentication if needed
if (AUTH.needed) {
console.log('Logging in...');
await page.goto(new URL(AUTH.loginUrl, BASE_URL).href);
// Smart login: try multiple common patterns for email/username field
const emailField = page.locator([
'input[type="email"]',
'input[name="email"]',
'input[id="email"]',
'input[placeholder*="email" i]',
'input[name="username"]',
'input[id="username"]',
'input[type="text"]',
].join(', ')).first();
await emailField.fill(AUTH.email);
// Smart login: try multiple common patterns for password field
const passwordField = page.locator([
'input[type="password"]',
'input[name="password"]',
'input[id="password"]',
].join(', ')).first();
await passwordField.fill(AUTH.password);
// Smart login: try multiple common patterns for submit button
const submitButton = page.locator([
'button[type="submit"]',
'input[type="submit"]',
'button:has-text("Sign in")',
'button:has-text("Log in")',
'button:has-text("Login")',
'button:has-text("Submit")',
].join(', ')).first();
await submitButton.click();
await page.waitForURL('[EXPECTED_AUTHENTICATED_URL]'); // replace with verified app route
console.log('Authenticated route reached');
}
// Capture each screenshot
for (const shot of SCREENSHOTS) {
console.log(`Capturing: ${shot.name}`);
await page.goto(`${BASE_URL}${shot.url}`);
await page.waitForLoadState('networkidle');
// Optional: wait for specific element
if (shot.waitFor) {
await page.waitForSelector(shot.waitFor);
}
// Optional: perform actions before screenshot
if (shot.actions) {
for (const action of shot.actions) {
if (action.click) await page.click(action.click);
if (action.fill) await page.fill(action.fill.selector, action.fill.value);
if (action.wait) await page.waitForTimeout(action.wait);
}
}
await page.screenshot({
path: `${SCREENSHOTS_DIR}/${shot.name}.png`,
fullPage: shot.fullPage || false,
});
console.log(` Saved: ${shot.name}.png`);
}
await browser.close();
console.log('Done!');
}
main().catch(error => { console.error(error); process.exitCode = 1; });
スクリプトの実行
node screenshot-script.mjs
実行後、一時スクリプトをクリーンアップします:
rm screenshot-script.mjs
Step 7: 高度なスクリーンショットオプション
要素にフォーカスしたスクリーンショット
ビューポート全体ではなく特定の要素をスクリーンショットするには:
const element = await page.locator('[CSS_SELECTOR]');
await element.screenshot({ path: `${SCREENSHOTS_DIR}/element.png` });
全ページのスクリーンショット
スクロール可能なコンテンツの場合、ページ全体をキャプチャします:
await page.screenshot({
path: `${SCREENSHOTS_DIR}/full-page.png`,
fullPage: true
});
アニメーションの待機
ページにアニメーションがある場合は、完了するまで待機します:
await page.waitForTimeout(500); // Wait 500ms for animations
スクリーンショット前の要素のクリック
モーダル、ドロップダウン、ホバー状態をキャプチャするには:
await page.click('button.open-modal');
await page.waitForSelector('.modal-content');
await page.screenshot({ path: `${SCREENSHOTS_DIR}/modal.png` });
ダークモードのスクリーンショット
アプリがダークモードに対応している場合:
// Set dark mode preference
const context = await browser.newContext({
viewport: { width: 1440, height: 900 },
deviceScaleFactor: 2,
colorScheme: 'dark',
});
Step 8: ファイル命名規則
並び順のために数値の接頭辞を付けた、説明的なケバブケースのファイル名を使用します:
| 機能 | ファイル名 |
|---|---|
| ダッシュボードの概要 | 01-dashboard-overview.png |
| リンク管理 | 02-link-inbox.png |
| エディションエディター | 03-edition-editor.png |
| アナリティクス | 04-analytics.png |
| 設定 | 05-settings.png |
ステップ 9:確認と要約
すべてのスクリーンショットをキャプチャした後、結果を確認します。
ls -la screenshots/*.png
sips -g pixelWidth -g pixelHeight screenshots/*.png 2>/dev/null || file screenshots/*.png
ユーザーに要約を提示します。
- 生成したすべてのファイルとそのパスを一覧表示します
- 解像度を確認します(1440x900 のビューポートで 2x Retina の場合は 2880x1800 になります)
- ファイルサイズの合計を記載します
- 次に行うことを提案します
出力例:
Generated 5 marketing screenshots:
screenshots/
├── 01-dashboard-overview.png (1.2 MB, 2880x1800 @ 2x)
├── 02-link-inbox.png (456 KB, 2880x1800 @ 2x)
├── 03-edition-editor.png (890 KB, 2880x1800 @ 2x)
├── 04-analytics.png (567 KB, 2880x1800 @ 2x)
└── 05-settings.png (234 KB, 2880x1800 @ 2x)
All screenshots are true retina-quality (2x deviceScaleFactor) and ready for marketing use.
エラー処理
- Playwright が見つからない場合:
npm install -D playwrightを提案します - ページが読み込まれない場合:開発サーバーが起動しているか確認し、起動を提案します
- ログインに失敗した場合:スマートロケーターは一般的なパターンを試しますが、通常とは異なるログインフォームでは失敗することがあります。ログインに失敗した場合は、ログインページの HTML を調べて正しいセレクターを特定し、スクリプトをカスタマイズします
- 要素が見つからない場合:CSS セレクターを確認し、代わりにページ全体のスクリーンショットを撮影することを提案します
- スクリーンショットの撮影に失敗した場合:ディスク容量を確認し、スクリーンショットディレクトリへの書き込み権限を確認します
最良の結果を得るためのヒント
- UI の状態を整える:現実的なコンテンツを表示するには、デモデータまたはシードデータを使用します
- サイズを統一する:すべてのスクリーンショットで同じビューポートを使用します
- コンテンツの表示を待つ:アプリ固有の準備完了セレクターを使用します。ネットワークがアイドル状態でも、コンテンツの準備が完了したとは限りません
- 開発ツールを非表示にする:ブラウザー拡張機能や開発用オーバーレイが表示されていないことを確認します
- ダークモード版:対応している場合は、ライトモードとダークモードの両方をキャプチャすることを検討します
制限事項
- このスキルは、タスクが上記の範囲に明確に該当する場合にのみ使用してください。
- 出力を、環境固有の検証、テスト、または専門家によるレビューの代わりとして扱わないでください。
- 必要な入力、権限、安全上の境界、または成功基準が不足している場合は、作業を中断して確認を求めてください。
このスクリプトはカスタマイズ可能な草案です。認証情報を送信する前にロケーターを確認してください。汎用的な先頭一致セレクターは、誤ったフォームを選択する可能性があります。スクリーンショットの撮影許可は、アカウントの変更、画像の公開、または第三者の非公開データの撮影を許可するものではありません。デモデータを使用し、すべての画像を確認して機密情報を伏せてください。出力ディレクトリ内で撮影画像のファイル名を検証し、既存の成果物を上書きしないようにしてください。ページ全体や要素の寸法はビューポートの例とは異なります。実際のピクセル数を確認してください。本番環境のツールでは、finally ブロック内でブラウザーを閉じてください。