seo-roast について
seo-roastは、Webサイトを運用するチーム向けのSEO監査スキルです。収益への影響で問題を分類し、軽微な警告よりクロール、インデックス、コンバージョンの阻害要因をコードで直すことを優先します。
主な機能
- 01問題を重大度と収益影響で分類
- 02robots.txt、サイトマップ、ルートの確認
- 03動的ページとロケール構成の監査
- 04ファーストビューと導線の確認
- 05AI検索での可視性と価格の確認
- 06収益ページのインデックスと内部リンク確認
活用シーン
- 01収益ページのクロール阻害要因の特定
- 02プログラムSEOページの改善
- 03AIクローラーが価格や製品情報を読めるようにする
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ illyism/ seo-skills --skill seo-roastインストール後、Claude Code で/seo-roastを入力して読み込まれたか確認します。
詳細
SEO Roast:売上最優先の徹底検証から、マージ済みの PR まで
多くの監査では、警告が 400 件並ぶ 50 ページの PDF が提出されます。代替テキストの欠落、メタディスクリプションが 4 文字長すぎる、H2 より先に H3 がある、といった内容です。重要な 3 つの問題が 31 ページ目に埋もれているため、サイトは売上を失い続けます。Roast はその逆を行います。売上を妨げる問題を見つけ、率直に伝え、コードで修正し、残りは売上への影響順に並べます。
呼び出し時: まず一行で判定を伝えます(「robots.txt が Google 以外のあらゆる検索エンジンからサイトを隠しています」)。その後、手順を実行します。100 点満点のスコアから始めてはいけません。
基本ルール:致命的な問題を最優先し、些末なことには手を出さない(致命的な問題がなくなるまで)
issue found
├── FATAL: blocks crawling, indexing, or rendering of a revenue page
│ └── Fix in this PR. Nothing else ships until this tier is empty.
├── REVENUE: page indexes but cannot rank or cannot convert
│ └── Fix in this PR if it takes under 1 hour of code, else top of roadmap.
├── COMPOUNDING: authority, links, AI visibility
│ └── Roadmap with owner and first action.
└── FLUFF: alt text, meta length, heading order, minor schema warnings
└── One line at the bottom of the roadmap. Do not fix while FATAL or REVENUE rows remain.
理由:Bing がクロールできないページに代替テキストを追加しても効果はありません。チームが些末な問題を先に直すと、問題を解決できたと感じる一方で、障害要因はその後も四半期にわたって残り続けます。
情報収集(2 分)
- ドメイン、売上につながる主要ページ 1~3 件、主なコンバージョン(サインアップ、デモ、購入)。
- リポジトリへのアクセス:
package.jsonからフレームワークを検出し、robots.txt/robots.ts、sitemap、ミドルウェア、動的ルート(app/**/[slug]、pages/**/[slug])を見つけます。 - 利用できる場合:GSC の上位ページ、Ahrefs または DataForSEO へのアクセス(ahrefs-research と dataforseo-serp を参照)。
6 項目の Roast 判定手順
順番に実行します。各項目にはチェック内容、合格/不合格の基準、実施する修正があります。
1. 自サイトのクロールとセーフサーチの阻害要因
1a. デフォルト拒否の robots.txt
curl -s https://deployfast.dev/robots.txt
失敗パターン:
User-agent: *
Disallow: /
User-agent: Googlebot
Allow: /
これにより、Bingbot、DuckDuckBot、Brave、Yandex、Naver、およびすべての AI 検索クローラーがブロックされます。致命的な理由:Bing のインデックスは ChatGPT 検索、Copilot、DuckDuckGo に情報を提供しているため、このファイル一つで、ほとんどの AI の回答からサイトが除外されます。
適用済みの修正: デフォルトで許可し、非公開パスのみをブロックします。
User-agent: *
Allow: /
Disallow: /api/
Disallow: /app/
Disallow: /admin/
Sitemap: https://deployfast.dev/sitemap.xml
/_next/、/static/、CSS/JS のパスは決して拒否しないでください。理由:Google はこれらのファイルを使ってページをレンダリングするため、ブロックするとレイアウトが壊れていると認識されます。AI 検索を維持しつつ AI 学習用クローラーをブロックするには、一律拒否ではなく block-ai-scrapers スキルを使ってください。
このリポジトリに存在する非公開パスのみを拒否します(/api/ は対象、ダッシュボードが /app/ にある場合のみ /app/ も対象)。curl -s https://deployfast.dev/sitemap.xml が XML を返さない場合は、同じ PR でサイトマップ(Next.js では app/sitemap.ts)を追加してください。理由:404 または HTML ページを指す Sitemap: 行では、修正が無駄になります。
1b. ロケールの乱立
サイトマップ内のロケールプレフィックス(/de、/fr、/ru、/es、...)を数えます。サイトマップがない場合は、ルートツリー(app/[locale]、i18n 設定、ミドルウェアのロケール一覧)を確認します。
locale trees
├── >= 8 locales, or any locale with English strings left in templates, or hreflang not reciprocal
│ └── FAIL. Keep a locale only if it earns >= 5% of the default locale's clicks or revenue
│ AND you translate every string on it in this PR (max 3 kept).
│ Others: noindex + remove from sitemap, or 301 to the English page.
│ No locale qualifies → keep the default locale only, ship no hreflang.
└── <= 3 locales, fully translated, reciprocal hreflang + x-default → PASS
理由:翻訳が不完全なロケールのツリーは、内容の薄い類似ページとなり、クロールバジェットを分散させるうえ、品質の低い機械翻訳と見なされます。相互設定とは、対象セット内の各ページが、自分自身を含むほかのすべてのページを指定することです。一方向の hreflang は無視されます。
適用済みの修正: 維持するロケールについて完全な相互設定を出力する hreflang ジェネレーター、除外するロケールに対するレイアウト内の noindex ガード、維持するロケールに絞り込んだサイトマップを追加します。Next.js の redirects() で 301 リダイレクトを設定する場合は、除外するロケールごとに 2 つのルールを記述します。/fr -> / と /fr/:path+ -> /:path+ です。理由:単一の /fr/:path* -> /:path* ルールでは、単独の /fr が空の Location ヘッダーにリダイレクトされます。Next.js の permanent: true は 308 を返しますが、Google はこれを 301 と同様に扱います。
1c. セーフサーチによる評価低下
クロール可能な HTML に、境界線上のコンテンツや NSFW メディアがないか確認します。ユーザーがアップロードしたアバターやギャラリー、性的な印象を与えるストック画像のヒーロー画像、成人向けに近い UGC が対象です。セーフサーチのオン/オフで site:domain の検索結果数を比較します。問題のない製品サイトで大きな差があれば FAIL です。理由:Google はページ単位およびサイト単位で露骨なコンテンツを分類し、多くのユーザーではセーフサーチがデフォルトでオンになっているため、露骨な画像が少数あるだけでも、主要な検索語句の検索結果から問題のないページが除外される可能性があります。
適用済みの修正: UGC メディアのページを noindex または認証の背後に置き、成人向けのページに限って <meta name="rating" content="adult"> を追加します。これにより、Google にサイト全体ではなく該当ページのみを分けて評価するよう伝えます。
1d. あらゆるパスに一致するソフト 404
curl -s -o /dev/null -w '%{http_code}\n' https://deployfast.dev/no-such-page-xyz # must print 404
200 が返る場合はすべて FAIL です。よくある原因は、トップレベルの動的セグメント(app/[locale]/page.tsx、pages/[slug].tsx)が、静的ファイルが優先されない場合に /sitemap.xml や /robots.txt を含むすべてのパスでレンダリングされることです。理由:タイプミスした URL がすべて、インデックス可能なホームページの重複になり、サイトマップの URL が HTML を返すことになります。
適用済みの修正: セグメントに export const dynamicParams = false(App Router)または fallback: false(Pages Router)を設定し、不明なパラメーターには notFound() を使います。
2. プログラマティック SEO の落とし穴と矛盾する件数
動的ルートをすべて列挙し、サイトマップから各ルートの実際の URL を 20 件ずつサンプルしてください。サイトマップがない場合は、generateStaticParams またはルートが読み込むデータファイルから列挙してください。
| 確認項目 | 不合格の基準 | 実施した修正 |
|---|---|---|
| 内容の薄い結果ページ | サンプルページの > 10% で結果が 0~1 件 | results < 3 の場合は noindex, follow を設定し、サイトマップから除外 |
| 数字または ID のスラッグ | /near/18234、/tools/a7f3 | エンティティ名からスラッグを生成し、旧 ID から 301 リダイレクト |
| 取引を示す名詞がない | 「X の近くの物件」 | テンプレート:「X の近くの賃貸コンドミニアム(42 件)」 |
| 定型文の FAQ | 子ページの > 30% で FAQ の回答文が同じ | エンティティ変数(件数、価格帯、上位項目)を挿入するか、ブロックを削除 |
| 検索 URL の肥大化 | ?q=、?sort=、?page= の URL がインデックス登録されている | まず noindex を設定し、インデックスから除外された後にのみ Disallow を設定 |
| 矛盾する件数 | H1、FAQ、llms.txt で異なる数値を記載 | 3 か所すべてで読み込む単一の定数を使用 |
それぞれが重要な理由:
- 内容の薄いページがあると、Google はルートパターン全体の価値が低いと判断するため、同じテンプレートを使う質の高いページの評価まで下がります。
- 検索ユーザーは行動を示す語句(「賃貸」「販売中」「無料」)を入力します。それがないタイトルは、含んでいるタイトルにクリックを奪われます。
noindexをDisallowより先に設定してください。クロールを禁止した URL はnoindexを確認するための再クロールができず、インデックスに残り続けるためです。- Google と LLM は 1 つの数値を引用します。H1 に 1,200、FAQ に 900 以上、
llms.txtに 800 と書かれていれば、どの数値も信用されません。 - 静的な
public/llms.txtから件数の定数をインポートすることはできません。ページと同じ定数から件数と価格を出力するルートハンドラー(app/llms.txt/route.ts)に置き換え、静的ファイルを削除してください。 - 定数はデータ(
TEMPLATES.length)から導出し、数値を直接入力しないでください。理由:データに行を追加した時点で、直接入力した件数はずれてしまいます。
3. ファーストビューのレイアウトとデモ壁の改善
3a. レイアウト
収益を生むページと主要なプログラマティックテンプレートを、1366x768 および 390x844 で読み込みます。
first viewport
├── map, hero animation, or video takes >= 50% of the viewport
│ AND no result card or internal hub link is visible
│ └── FAIL. Collapse the map behind a "Show map" toggle, render cards first.
├── card attributes are icon-only SVGs (bed icon + "2")
│ └── FAIL. Write them as text: "2 bedrooms, 1 bathroom, 65 m²".
└── cards and hub links visible without scrolling → PASS
理由:クローラーもユーザーも最初に読み込まれる内容を重視します。また、アイコンのみの属性は、Google や HTML を読む LLM にはテキストとして認識されません。
3b. デモ壁
primary CTA
├── only "Book a Demo" or "Talk to Sales"
├── or core value hidden behind "Create Account to View"
│ └── FAIL. Ship an instant interactive element on the page:
│ lookup, calculator, sample report, or live preview with no login.
│ Capture the email after the user sees their result.
└── visitor gets value in < 30 seconds without an account → PASS
理由:検索から訪れたユーザーは、予備知識のない状態でアクセスし、数秒で離脱します。一方、デモの予約カレンダーは、何かを見せる前に 30 分の時間を求めます。即座に結果を表示すれば、同じユーザーをコンバージョンにつなげ、Google にエンゲージメントのシグナルを送れます。
4. 見せかけの権威性と競合他社の優良リンクの実態確認
自社サイトと競合 3 社の DR、org_keywords、およびクリーンな参照ドメイン(ahrefs-research Workflow B:dofollow、コンテンツ内、ドメインごとに 1 件、参照元ページのトラフィック > 10)を取得します。
site profile
├── DR >= 40 and org_keywords < 100
│ └── FAIL: inflated. Links come from sitewides, widgets, or farms. Stop buying that kind.
├── competitor ranks top 3 on 25-40 clean editorial domains, site has fewer
│ └── That gap is the link target. Put the exact number in the roadmap.
└── clean domain count >= competitors' → links are not the bottleneck. Look at points 2, 3, 6.
理由:DR は簡単に水増しでき、偽装にも費用はかかりません。一方、クリーンな編集コンテンツのドメインこそ、リソースの限られた競合がランキングを獲得する要因です。実際の数値を明示し、チームが見栄えだけの指標を追いかけるのをやめさせましょう。
製品に組み込まれた被リンクの循環。 製品の利用を通じてリンクが獲得できているか確認します。
- 顧客向けの出力(ステータスページ、フォーム、請求書、レポート)に表示する「Powered by [Brand]」または「Verified on [Brand]」バッジ。
- ブランドリンクを含み、インデックス登録できる公開共有 URL(
/s/<id>、/r/<slug>)。 - 帰属表示リンクを含む、埋め込み可能なウィジェット、マップ、チャート。
実施した修正: バッジコンポーネントと埋め込み用スニペットを追加しました。ブランド名をアンカーテキストにしてホームページへリンクします。理由:Google はウィジェット内のキーワードを含むアンカーテキストをリンクスキームとみなします。一方、実際の利用から生まれるブランド名のアンカーは、アウトリーチなしでも効果が積み重なります。
5. AI 検索におけるエンティティと価格の可視性
for UA in GPTBot OAI-SearchBot PerplexityBot ClaudeBot; do
echo "$UA: $(curl -s -A "$UA" https://deployfast.dev/pricing \
| perl -0pe 's/<script\b.*?<\/script>//gs; s///gs; s/<head>.*?<\/head>//s' \
| grep -oE '\$[0-9][0-9,.]*' | sort -u | tr '\n' ' ')"
done
grep を実行する前に、スクリプト、コメント、<head> を取り除きます。理由:Next.js は RSC ペイロードを <script> タグ内にインライン化し、そこでは $1 や $9 が参照として使われるため、JS のみの価格ページでも生の grep を通過してしまいます。また、React は ${price} を $29 のように分割するため、固定価格のページがチェックに失敗することがあります。さらに、<title> 内の価格は価格表ではありません。まだデプロイはしないでください。next build && next start(またはフレームワークの本番サーバー)を実行し、ループの接続先を localhost にします。
pricing page raw HTML
├── no prices in the HTML (JS-only slider, client-fetched plans) → FAIL
├── docs or specs behind login → FAIL
├── crawler gets 403 / challenge page → FAIL (check WAF and bot rules)
└── plans, prices, and limits present as plain text → PASS
理由:ほとんどの AI クローラーは JavaScript を実行しません。そのため、JavaScript のみで実装された価格スライダーでは、ChatGPT、Perplexity、Claude に公開価格がないと伝わり、価格を読み取れる競合他社を勧められてしまいます。
**対応済みの修正:**価格表をテキストとしてサーバーサイドレンダリングし、主要機能の公開ドキュメントを公開し、同じ価格を記載した Product/Offer JSON-LD を追加し、llms.txt をページと完全に一致させます。
6. 収益ページのインデックス登録と内部リンクの実態
収益ページごとに確認します。
| 確認項目 | 不合格条件 |
|---|---|
| サイトマップに含まれている | 含まれていない |
インデックス登録済み(GSC URL 検査または site: クエリ) | インデックス未登録 |
| canonical | 別のページを指している、またはクエリ違いのページに設定されていない |
| ホームページまたはメインナビからリンクされている | いいえ |
| 本文内の文脈に沿ったリンク(ナビとフッターを除く) | 3 件未満 |
| ステータス | リダイレクトチェーンまたはソフト 404 がある |
理由:収益ページはクリックを 4 回以上重ねないとたどり着けない場所にある一方、ブログにはホームページからリンクされることがよくあります。その結果、Google は収益につながるキーワードでブログを上位表示し、コンバージョンに至りません。
**対応済みの修正:**ナビまたはホームページからリンクし、canonical を修正し、サイトマップにエントリーを追加します。その後、内部リンクのスキルを実行し、トラフィック上位の投稿から文脈に沿ったリンクを 3 件以上追加します。同じくナビを除外して件数を数えるため、孤立ページの一覧とこのチェックの結果は一致します。
必須の納品物
1. 修正 PR
FATAL と迅速に対応できる REVENUE の修正をすべてコードベースに直接適用します。対象は robots.txt、hreflang と noindex のガード、プログラムによるタイトルのテンプレート、件数の定数、クロール可能な価格とカード、バッジコンポーネント、内部リンクです。PR の説明には次の形式を使用します。
## SEO Roast fixes
Verdict: <one blunt line>
### Fatal (fixed)
- robots.txt default-deny blocked Bing and AI crawlers → default-allow
### Revenue (fixed)
- /near/[slug] titles now "Condos for Rent near {city} ({count} listings)"
### Verify
- curl -A Bingbot https://<domain>/robots.txt
- view-source pricing page shows $ amounts
2. seo/roast-roadmap.md
監査カテゴリではなく、収益への影響が大きい順に並べます。
# SEO Roast Roadmap: invoicekit.io (2026-11-12)
Verdict: Google could see you. Nobody else could.
| # | Tier | Issue | Revenue impact | Fix | Owner | Status |
|---|---|---|---|---|---|---|
| 1 | FATAL | robots.txt blocked all non-Google crawlers | AI search + Bing traffic at 0 | default-allow | agent | shipped in PR |
| 2 | REVENUE | Pricing JS-only | Missing from AI recommendations | SSR table + JSON-LD | agent | shipped in PR |
| 3 | COMPOUNDING | 11 clean RDs vs competitor 34 | Money keyword stuck page 2 | 23-link gap plan | founder | next |
## Fluff (ignore until rows above ship)
- 14 images missing alt text
「収益への影響」列には、どのような収益を妨げているのかを、簡潔な一文で記載します。重要度スコアや信号機の色は使用しません。
3. クライアント向けデッキ(任意)
roast を創業者、取締役会、またはクライアントに提出する場合は、seo/roast-roadmap.md を GenPPT で .pptx に変換します。各 FATAL の問題につき 1 枚のスライドで修正前/修正後を示し、その後にロードマップの表を掲載します。
次のステップ
- **人による詳細な分析:**Ilias が録画した、サイトに対する率直な 20 分間の動画 roast を利用するには、SEO Roast をご覧ください。
- ポイント 4 のリンクギャップを埋める:LinkDR(
https://linkdr.com/SKILL.md)は、精査済みの DR 30〜60 以上のエディトリアルリンクとリスティクルでの掲載を獲得します。これにより、23 件のリンク不足を、四半期分のアウトリーチではなく、注文 1 件で解消できます。 - ポイント 1a と 5 の AI 検索からの回復を検証する:AI SEO Tracker(MCP:
https://aiseotracker.com/api/agent/mcp)は、クロールと価格の修正を反映した後に、ChatGPT、Perplexity、Gemini、Google AI Overviews がページを引用し始めるかを追跡します。
完了チェックリスト
- FATAL 項目がなく、修正がすべて PR に含まれている
- 迅速に対応できる REVENUE の修正が PR に含まれ、残りはロードマップの上位に記載されている
-
seo/roast-roadmap.mdが収益への影響順に並び、担当者が割り当てられている - PR の説明に記載した検証コマンドがすべて成功する
- 些細な指摘は末尾に一度だけ記載し、手を加えていない
関連項目
- 競合他社との差分と正確な被リンク分析:ahrefs-research、https://il.ly/skills/ahrefs-research
- SERP の意図、クラスタリング、AI の引用元:dataforseo-serp、https://il.ly/skills/dataforseo-serp
- 収益ページを 30 日で検索結果 1 ページ目へ:blitz-seo、https://il.ly/skills/blitz-seo
- AI クローラーのポリシー:block-ai-scrapers、https://il.ly/skills/block-ai-scrapers
- ブログのトラフィックを収益ページへ誘導:internal-linking、https://il.ly/skills/internal-linking