This is the power user version of the SEO audit skill. It runs every check from the basic audit, then layers on social media tags (Open Graph and Twitter Cards), content quality analysis, and deeper technical validation. You'd reach for this when someone asks for a "full report" or "technical audit" instead of a quick scan. The output is a detailed HTML report saved to disk, never dumped to terminal. Built on a two-phase architecture where Phase 1 reuses all the basic Python scripts (robots.txt, schema, on-page elements) and Phase 2 adds the full-only modules. The LLM reviews things scripts can't judge, like whether your og:title is actually optimized for social sharing or just a copy-paste of the page title.
npx -y skills add jeffli1993/seo-audit-skill --skill seo-audit-full --agent claude-codeInstalls into .claude/skills of the current project.
This skill runs a full single-page SEO audit from the seo-audit-full directory.
It does not route to seo-audit when only a URL is provided.
Use seo-audit-full when the user asks for:
URL-only requests are valid. When external datasets are not supplied, run the full public-signal workflow and clearly note missing data sources in the report.
| Input | Required | Notes |
|---|---|---|
| Page URL | Yes | The primary page to audit |
| Primary keyword | Recommended | Improves content relevance scoring |
| PageSpeed API key | Yes | Required for full audit PageSpeed checks. Ask at the start and do not run PageSpeed without it. |
| Raw HTML or page content | Optional | Enables more accurate content checks when supplied |
| GSC / crawl / analytics data | Optional | Include when supplied, otherwise mark unavailable |
| Competitor benchmark data | Optional | Include when supplied |
At the start of a full audit, ask the user for a PageSpeed Insights API key:
For PageSpeed checks, please provide a Google PageSpeed Insights API key.
Get one here: https://developers.google.com/speed/docs/insights/v5/get-started
Open "Acquiring and using an API key" → "Get a Key".
If you do not provide one, I will stop before running the full audit because
PageSpeed is a required full-audit module.
Do not run seo-audit-full PageSpeed checks without a PageSpeed API key supplied
by --api-key, PAGESPEED_API_KEY, or GOOGLE_PAGESPEED_API_KEY. If the key is
missing, stop and ask the user to configure it instead of rendering a full report
with missing PageSpeed data.
┌─────────────────────────────────────────────────────────────┐
│ seo-audit-full Workflow │
│ │
│ Phase 1: Run core scripts (./scripts/) │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ check-site.py → robots.txt, sitemap, 404, URL │ │
│ │ check-page.py → title, H1, meta desc, slug │ │
│ │ check-schema.py → JSON-LD validation │ │
│ │ fetch-page.py → raw HTML for analysis │ │
│ └──────────────────────────────────────────────────────┘ │
│ ↓ │
│ Phase 2: Run performance + full-only scripts (./scripts/) │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ check-pagespeed.py → Lighthouse scores + metrics │ │
│ │ check-social.py → OG Tags + Twitter Card │ │
│ │ (more scripts added here as modules grow) │ │
│ └──────────────────────────────────────────────────────┘ │
│ ↓ │
│ Phase 3: LLM-only advanced checks │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ E-E-A-T content quality scoring │ │
│ │ Duplicate content signals │ │
│ │ Anchor text quality assessment │ │
│ └──────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
Produce an Advanced Full SEO Audit Report by filling the template at assets/report-template.html, then save it to a file — never print raw HTML to the terminal.
File naming: reports/<hostname>-<slug>-full-audit.html
https://example.com/blog/best-tools → reports/example-com-blog-best-tools-full-audit.html
https://example.com/ → reports/example-com-full-audit.html
After saving, tell the user:
✅ Full Report saved → reports/example-com-full-audit.html
Open it now? (yes / no)
If yes → run: open reports/example-com-full-audit.html
Template placeholders — fill each independently:
| Placeholder | Content |
|---|---|
{{summary_verdict}} | One sentence: total checks run, how many failed/warned/passed |
{{summary_critical_html}} | <li> per critical item, or <li class="summary-empty">None</li> |
{{summary_warnings_html}} | <li> per warning item, or <li class="summary-empty">None</li> |
{{summary_passing_html}} | <li> per passing check, or <li class="summary-empty">None</li> |
{{pagespeed_checks_html}} | Full PageSpeed module using check-pagespeed.py output |
{{site_checks_html}} | Site-level check tables |
{{eeat_checks_html}} | E-E-A-T trust page table |
{{page_checks_html}} | Page-level check tables, including full-only additions |
{{priority_actions_html}} | Ordered priority action list |
{{insights_html}} | Optional finding walkthrough cards |
Run full scripts from this directory. All output is structured JSON — use it directly as evidence.
Dependencies: pip install requests
# 1. site-level checks (robots.txt + sitemap.xml + 404 + URL canonicalization)
python scripts/check-site.py https://example.com
# 2. page-level checks (H1, title, meta description, canonical, URL slug)
python scripts/check-page.py https://example.com --keyword "primary keyword"
# 3. fetch raw HTML for downstream scripts
python scripts/fetch-page.py https://example.com --output /tmp/page.html
# 4. JSON-LD schema validation
python scripts/check-schema.py --file /tmp/page.html
# 5. PageSpeed / Lighthouse checks
python scripts/check-pagespeed.py https://example.com --strategy mobile --timeout 180 --api-key "USER_PROVIDED_KEY"
# If no key was provided, do not run this command. Ask the user to configure a PageSpeed API key first.
# 6. Social tags: OG + Twitter Card validation
python scripts/check-social.py --file /tmp/page.html
# Or directly from URL:
python scripts/check-social.py https://example.com
Each script exits with code 0 (all pass/warn) or 1 (any fail/error).
PageSpeed can take 200 seconds. Use a 180-second timeout by default. If it
still times out, mark the Page Speed module as error and state that the
PageSpeed API timed out; do not treat that as confirmed page performance failure.
If PageSpeed fails because Google returns a quota/API-key error after a key was
provided, keep the audit running and render the PageSpeed module as error with
this instruction:
Get a PageSpeed API key at https://developers.google.com/speed/docs/insights/v5/get-started → "Acquiring and using an API key" → "Get a Key".
Full runs its own core checks plus the full-only items marked ★ below.
{{site_checks_html}})Core checks:
Staging Subdomain Indexation rules:
test., staging., dev., preview., beta., uat.noindex, or a blocking robots.txt.noindex, or Disallow: /.test.example.com and www.example.com as separate but near-identical URLs, splitting ranking signals and competing with the production site.User-agent: * + Disallow: /; add page-level noindex if pages can still be accessed.Sitemap URL Inventory rules:
{{site_checks_html}}, before the Crawlability table.check-site.py sitemap_inventory output to summarize first-level directories, URL counts, inferred page types, and one representative example URL.info unless sitemap URLs cannot be parsed; do not penalize a site for having many or few URLs in a directory without deeper evidence./blog/, /tools/, /alternatives/, /templates/, or /use-cases/.{{pagespeed_checks_html}})Full-only:
{{eeat_checks_html}})Core checks:
Contact logic (Contact row only):
/contact page is not required/contact alone is not a fail when About or footer/nav already expose contact infoE-E-A-T infrastructure rules — two layers per trust page:
| Page | Required |
|---|---|
| About Us | Yes |
| Contact | Yes — dedicated page optional; About or footer/nav contact details satisfy this |
| Privacy Policy | Yes |
| Terms of Service | Yes |
| Media / Partners | No — include only if present |
Status rules (About, Privacy, Terms, Media/Partners):
Contact-specific rules:
/contact, /contact-us) — HTTP 200 counts as Existsmailto:, visible email, social links, or a contact form/contact when About or footer already expose contact info{{page_checks_html}}), output in this exact order:Core checks: URL Slug · Title Tag · Meta Description · H1 Tag · Canonical Tag · Image Alt Text · Word Count · Keyword Placement · Heading Structure · Internal Links · Schema (JSON-LD)
Schema (JSON-LD) rules:
@type, required fields, recommended rich-result fields, nested fields, and primary-type conflicts.inLanguage, or localized schema cannot be fully confirmed.inLanguage, language-specific headline/description where present, and url / mainEntityOfPage pointing to the current localized canonical URL.★ Full-only additions:
Same rules across full audit modules — map each field's status directly to the report check table:
status → pass / warn / fail / error → badge in reportdetail → starting point for Evidence lineFor check-site.py output:
staging_subdomains.status → Staging Subdomain Indexation row statusstaging_subdomains.detail → Staging Subdomain Indexation row detailstaging_subdomains.public_hosts → evidence for public staging/test hostsstaging_subdomains.similar_hosts → fail evidence for production-like staging duplicatesrobots.status → robots.txt row statussitemap.status → sitemap.xml row statussitemap_inventory.status → Sitemap URL Inventory module statussitemap_inventory.directories[] → table rows with path, url_count, page_type, and example_urlsitemap_inventory.detail → short explanatory note below the inventory tableFor check-schema.py output:
status → Schema (JSON-LD) row statusdetail → Schema (JSON-LD) row detailparse_errors → fail evidence for malformed JSON-LDschemas[].fields_missing → fail evidence for missing required schema fieldsschemas[].recommended_missing and schemas[].nested_issues → warning evidencelocalized_schema.status → language/URL alignment status for multilingual schemalocalized_schema.issues → evidence for schema language or URL mismatchFor check-social.py output:
og.status → OG Tags row statustwitter_card.status → Twitter Card row statusog.fields.* → individual field details for the detail celltwitter_card.fields.* → individual field details, note fallback fieldsFor check-pagespeed.py output:
status → overall Page Speed statuscategory_status → Lighthouse Scores badge statusmetric_status → Core Lab Metrics badge statusfinal_url → Final URL linecategories.performance.score → Performance scorecategories.accessibility.score → Accessibility scorecategories["best-practices"].score → Best Practices scorecategories.seo.score → SEO scorecompact_metrics.fcp.display_value → FCPcompact_metrics.lcp.display_value → LCPcompact_metrics.tbt.display_value → TBTcompact_metrics.cls.display_value → CLScompact_metrics.si.display_value → Speed Indexscreenshot truthy → Screenshot availableDo not use overall status for the Lighthouse Scores badge. Category scores use
Lighthouse thresholds: 90–100 pass, 50–89 warn, 0–49 fail. Example: Performance
60, Accessibility 84, Best Practices 100, SEO 100 means category_status is
warn. If LCP or Speed Index fails, metric_status and overall status may be
fail while the Lighthouse Scores panel remains warn.
Inside {{pagespeed_checks_html}}, include a short Priority Actions list after
the score/metric cards. Keep it to 2–4 concise items based on failing or warning
PageSpeed fields:
Always include the official diagnostic link:
https://pagespeed.web.dev/
Resolve every llm_review_required: true field before writing the report:
H1 semantic judgment, Title keyword position, URL Slug evaluation, and Meta
Description quality must all receive an explicit judgment.
OG Tags quality (always review):
og:title : Does it differ meaningfully from <title>? It should be optimized for social sharing.
og:description : Is it compelling for social feeds? Different focus than meta description is OK.
og:image : Is the URL an actual image path (not a page URL)?
Twitter Card completeness:
If twitter:card is "summary_large_image", twitter:image (or og:image fallback) must be
at least 300x157px. Flag if the image URL looks like a small icon or favicon.
reports/<hostname>-<slug>-full-audit.htmlUse strict formatting:
Pass → one short phrase. No lists, no elaboration.
Warn → one <div class="detail-issue"> with ≤2 bullet points. One <div class="detail-fix">.
Fail → same as Warn. Lead with the exact failure.
**Finding: [Finding Title]**
- **Evidence:** [Observable fact, data point, or marked assumption]
- **Impact:** [SEO / UX consequence]
- **Fix:** [Actionable recommendation with example]
For Priority Actions, add effort/impact tags:
1. [High Impact / Low Effort] Fix og:image — social shares currently show no preview.