Analyze a website's UI/UX, category, style, performance, surface security, and SEO; emit structured JSON. Use for URL audits or website-cloner input. Don't use for penetration tests, full SEO audits, or App Store ASO.
Installer avec Codex ou Claude Copiez ce prompt, collez-le dans Codex, Claude ou un autre assistant, puis laissez-le vérifier la page du skill et l'installer pour vous.
Une commande directe contourne le prompt de vérification. Examinez la source avant de l'exécuter.
Analyze a website's UI/UX, category, style, performance, surface security, and SEO; emit structured JSON. Use for URL audits or website-cloner input. Don't use for penetration tests, full SEO audits, or App Store ASO.
WebFetch(url=<url>, prompt="Extract all HTML structure, meta tags, headings, links, images, scripts, styles, and any structured data (JSON-LD, Open Graph, etc.)")
If WebFetch fails (4xx, 5xx, timeout), return immediately:
For JS-heavy SPAs where WebFetch returns minimal content, note:
{"note": "SPA detected — analysis based on crawlable content only; some metrics may be incomplete"}
Exposed metadata (dev tools, debug endpoints, sensitive data in comments)
Always label as surface-level.
Step 5: SEO Scoring
Compute each dimension's 0–100 sub-score using the rubrics below, then combine with the weights to yield the overall seo.score. Round each sub-score to the nearest integer; the final score is round(Σ weight_i × sub_i).
Dimension
Weight
Sub-score rubric (0–100)
Meta tags (title + description)
20%
Start at 0. +50 if <title> is present and 10–60 chars. +50 if <meta name="description"> is present and 50–160 chars. Subtract 25 each for: title outside 10–60, description outside 50–160, duplicate title across siblings (when crawlable). Floor at 0.
Heading structure
15%
100 if exactly one <h1> and at least one <h2>. 70 if exactly one <h1> but no <h2>. 40 if zero or multiple <h1>s. Subtract 20 if any heading level is skipped (e.g. h2 → h4). Floor at 0.
Image alt text coverage
15%
round(100 × non_empty_alt_count / total_img_count). If total_img_count == 0, report 100 (no images = no alt-text debt). Decorative images using alt="" count as "non-empty intent" only when paired with role="presentation"; otherwise count as missing.
Structured data
20%
100 if at least one valid JSON-LD block is present and parses (any schema). 60 if only Open Graph or Twitter Card meta tags are present (no JSON-LD). 30 if only microdata or RDFa. 0 if none.
Crawlability (canonical, robots, sitemap)
30%
Start at 0. +40 if a <link rel="canonical"> resolves to an absolute URL. +30 if robots.txt is fetchable and not Disallow: /. +30 if a sitemap is referenced (via robots.txtSitemap: directive, <link rel="sitemap">, or a fetchable /sitemap.xml). Cap at 100.
When a sub-score cannot be computed (e.g. robots.txt unreachable), record the dimension as null in dimension_scores and exclude it from the weighted sum, redistributing its weight proportionally across the remaining dimensions. Note any nulls in seo.notes.
Step 6: UI/UX, Category, Style
Layout: Infer from HTML structure (divs, sections, nav, main, footer)
Category: saas-landing | portfolio | e-commerce | blog | docs | dashboard | marketing-site | web-app | other
Style: Typography, color palette, spacing density, motion indicators, aesthetic vibe
Edge Cases and Error Handling
Failure
Behavior
Unreachable (4xx/5xx/timeout)
{"error": "unreachable"} — stop
JS-heavy SPA
Note limitation, proceed with crawlable content
Paywall / login
{"error": "paywall"} — stop
Redirect loop
{"error": "redirect-loop"} — stop
Empty page
{"error": "empty"} — stop
Acceptance Criteria
Verify the expected output before reporting success:
JSON parses and contains url, timestamp, ui_ux, category, style, performance, security, and seo.
seo.score is an integer from 0 through 100 and matches the weighted, null-adjusted dimension calculation.
Performance estimates use lcp_estimate_seconds, unitless cls_estimate, ttfb_estimate_seconds, and total_page_weight_kb, plus an explicit static-analysis limitation.
Every unavailable measurement is null or an error field, never an invented value.
The output is written to the requested destination; assert the file exists and can be parsed when a path is supplied.