jeffli1993/seo-audit-skill/seo-audit

Claude Code and agent skill by jeffli1993/seo-audit-skill

Trust tier 3
  • community
Source check pending

Checking that the SKILL.md file is still in the repository.

An SEO agent skill for quick, lightweight, default single-page SEO audits. Performs basic on-page and site-level checks and outputs a structured basic SEO audit report. Use when the user asks for "SEO audit", "SEO check", "check my page SEO", "page analysis", or wants a first-pass review of a URL. If the user requests "deep audit", "full report", "technical SEO audit", or "advanced SEO", use seo-audit-full instead.

Install

npx vskill@latest install jeffli1993/seo-audit-skill/seo-audit

SKILL.md

seo-audit — Basic SEO Audit

A lightweight SEO agent skill designed for quick, default single-page SEO audits. Powered by OpenClaw. Suitable for first-time page checks or when a rapid assessment is needed without full technical depth.


When to Use This Skill

Use seo-audit when:

  • The user says: "audit this page", "check SEO", "analyze my URL", "quick SEO check", "what's wrong with my page"
  • No specific depth is requested — this is the default entry point
  • The user needs a fast, readable summary rather than a comprehensive technical breakdown

If the user wants more depth, upgrade to seo-audit-full:

Tip: For deep technical audits, advanced on-page SEO, or full reports, use the seo-audit-full skill.

Input Expected

InputRequiredNotes
Page URLYesThe page to audit
Raw HTML or page contentOptionalEnables more accurate on-page analysis
GSC / analytics dataOptionalNot required for basic audit

If only a URL is provided and no source code or crawler data is available, clearly state:

Limitation: This audit is based on visible page content and publicly available signals only. Source code, GSC data, crawl logs, and performance metrics are not available for this audit.

Output

Produce a Basic 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>-audit.html

https://example.com/blog/best-tools → reports/example-com-blog-best-tools-audit.html
https://example.com/ → reports/example-com-audit.html

After saving, tell the user:

✅ Report saved → reports/example-com-audit.html
Open it now? (yes / no)

If yes → run: open reports/example-com-audit.html


Template placeholders — fill each independently:

PlaceholderContent
{{summary_verdict}}One sentence: total checks run, how many failed/warned/passed
{{summary_critical_html}}<li> per critical (fail) 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>

Scripts

Run these scripts before writing any findings. They output structured JSON — use the JSON directly as evidence; do not re-fetch the same URLs manually.

Dependencies: pip install requests (html parsing uses Python stdlib)

bash
# Step 1: site-level checks (robots.txt + sitemap.xml)
python scripts/check-site.py https://example.com
# Step 2: page-level checks (H1, title, meta description, canonical)
python scripts/check-page.py https://example.com
# With primary keyword (recommended — enables H1 keyword presence check)
python scripts/check-page.py https://example.com --keyword "running shoes"
# Optional: fetch raw page HTML for further inspection
python scripts/fetch-page.py https://example.com --output page.html
# Step 3: JSON-LD schema validation
python scripts/check-schema.py https://example.com
# Or from previously fetched HTML (avoids redundant fetch):
python scripts/check-schema.py --file page.html

Each script exits with code 0 (all pass/warn) or 1 (any fail/error).

STRICT SCOPE — do not add any check not listed below. No exceptions.

Allowed site-level checks (in {{site_checks_html}}):

  • robots.txt · sitemap.xml · 404 Handling · URL Canonicalization · i18n / hreflang

Allowed E-E-A-T checks (in {{eeat_checks_html}}):

  • About Us · Contact · Privacy Policy · Terms of Service · Media/Partners (only if present)

Contact logic (Contact row only):

  • A dedicated /contact page is not required
  • Pass if contact is reachable via any of: dedicated contact page (HTTP 200) · About page with contact details · footer/nav mailto, email, social links, or contact form
  • Fail only when no contact pathway exists anywhere on the site
  • Missing /contact alone is not a fail when About or footer/nav already expose contact info

Allowed page-level checks (in {{page_checks_html}}), output in this exact order: URL Slug · Title Tag · Meta Description · H1 Tag · Canonical Tag · Image Alt Text · Word Count · Keyword Placement · Heading Structure · Internal Links · Schema (JSON-LD)

Image Alt Text logic:

  • Parse <img> tags from static HTML
  • Pass: all images have non-empty alt (decorative images with alt="" are OK)
  • Warn: any content image missing alt attribute
  • Unverified (status-info): 0 images found in static HTML → likely JS-rendered, cannot verify

⛔ HARD RULE — Output ONLY the check rows defined in report-template.html. If a check is not in the allowed lists above, do NOT output it — not even if you find issues. No exceptions. No "bonus" checks. No improvisation. The template is the single source of truth. Treat it as a strict whitelist.

Still BANNED (belong to seo-audit-full): OG tags · Twitter Card · Social tags · Page Weight · Core Web Vitals · Robots Meta

How to use the JSON output:

  • Map each field's status → pass / warn / fail / error directly to the report check table
  • Use each field's detail string as the starting point for the Evidence line in findings
  • Do not contradict the script output unless you have additional observable evidence
  • Separate check groups with <div class="subsection-label">Label</div> inside {{site_checks_html}}:

Crawlability · URL Canonicalization · i18n / hreflang · Schema (JSON-LD) and <div class="subsection-label">E-E-A-T Trust Pages</div> before {{eeat_checks_html}}

LLM review — mandatory when `llm_review_required: true`:

The script flags fields that require semantic or quality judgment it cannot perform. Never leave llm_review_required: true unresolved — always make an explicit judgment call.

H1 — triggered when `keyword_match == "partial"`:

h1_text : (from h1.values[0])
keyword : (the --keyword passed to the script)
Judge: Does this H1 semantically cover the keyword's search intent?
- Consider synonyms, natural variants, topic coverage
- yes → downgrade to "pass", note the variant
- no → keep "warn" or upgrade to "fail", explain the gap

Title — triggered when `keyword_match == "partial"` OR `keyword_position != "start"`:

title : (from title.value)
keyword : (the --keyword passed)
Judge:
1. Does the title semantically cover the keyword's search intent?
2. Is the title grammatically correct and naturally readable?
3. Keyword position — apply different standards by page type:
- Homepage : Brand + core keyword is correct (e.g. "Acme | AI Workflow Automation")
Do NOT flag brand-first as a problem.
- Inner pages: Core keyword should lead (e.g. "AI Workflow Automation for Teams — Acme")
Flag if keyword is buried mid-title without good reason.
IMPORTANT — do NOT flag these as negatives:
- Years (e.g. "2026") → signal freshness, increase CTR — treat as positive unless
the page is explicitly evergreen content where dating would hurt longevity.
- Numbers (e.g. "5 best", "Top 10", "3 steps") → set clear expectations,
consistently outperform non-numeric titles in CTR — always treat as a plus.
- Specific qualifiers ("Open-Source", "Self-Hosted", "Free") → narrow intent
and attract higher-quality clicks — do not penalize.

URL Slug — triggered when `keyword_match != "full"` or `is_homepage == false`:

slug : (from url_slug.slug)
keyword : (the --keyword passed)
Judge:
1. Does the slug contain the primary keyword or a natural variant?
2. Is the path hierarchy logical? (/category/keyword is ideal)
3. Is it concise and human-readable?
Homepage (is_homepage: true): skip — no judgment needed.

Meta Description — always triggered when content is present:

meta_description : (from meta_description.value)
keyword : (the --keyword passed)
Judge all four:
1. Complete sentence(s)? (1-2 sentences, no fragments)
2. Mentions a concrete result — not vague fluff?
Good: "Cut design time by 60% with AI-powered templates"
Bad: "The best tool for all your design needs"
3. Keyword or natural synonym used once — not stuffed?
4. More specific than what a typical competitor would write?
IMPORTANT — do NOT flag these as negatives:
- Years (e.g. "2026") → signal freshness, improve CTR for time-sensitive queries.
Only note the year if the page is explicitly evergreen content where dating hurts.
- Numbers (e.g. "5 best", "3 steps") → concrete specificity, strong CTR signal.
- Trailing "and more." → minor style note at most, never a Warning or Fail.

Recommended Workflow

Follow these steps in order:

  1. Acknowledge scope — confirm this is a basic audit; note any missing data
  1. Infer primary keyword — fetch the page with fetch-page.py, then determine the primary keyword:
  • If the user explicitly provided a keyword → use it directly
  • If not → read the page H1, title, and first paragraph, then infer the single most likely

target keyword phrase (what would a searcher type to find this page?)

  • State the inferred keyword explicitly before running checks:

> "Inferred primary keyword: open source claude alternatives"

  1. Run `check-site.py` — parse the JSON output for robots, sitemap, 404 handling, and URL canonicalization

404 check: fetch <origin>/this-page-definitely-does-not-exist-seo-audit-check

  • Returns 404 → Pass · Returns 200 (soft 404) → Fail · Returns 301 to homepage → Warn

URL Canonicalization checks (each is a separate sub-check):

  • HTTP→HTTPS: fetch http://<host> — must 301 to https://. Returns 200 → Fail.
  • www consistency: fetch both https://www.<host> and https://<host> — one must 301 to the other. Both return 200 → Warn.
  • Trailing slash: compare the URL actually served vs the canonical tag on the page. Mismatch → Warn.
  • Canonical match: canonical tag href must exactly match the final URL after all redirects. Mismatch → Warn.
  1. E-E-A-T infrastructure check — for each trust page below, check two layers:
  • Layer 1 — Exists: fetch the URL, check HTTP status (200 = exists, 404/redirect = missing)
  • Layer 2 — Reachable: fetch homepage HTML, check if footer or nav contains a link to this page
PageRequired
About UsYes
ContactYes — see Contact-specific rules below
Privacy PolicyYes
Terms of ServiceYes
Media / PartnersNo — include only if present

Status rules (About, Privacy, Terms, Media/Partners):

  • Page missing (non-200) → Fail
  • Page exists but not linked in footer/nav → Warn
  • Page exists and linked in footer/nav → Pass
  • Optional page missing → skip, do not include row

Contact-specific rules — a dedicated /contact page is optional:

  1. Try common paths (/contact, /contact-us) — HTTP 200 counts as Exists
  2. If no contact page, check the About page body for email, social, or contact details
  3. Also scan homepage footer and nav for mailto:, visible email, social links, or a contact form
  4. Exists Pass if any contact pathway is found (dedicated page, About, or footer/nav contact details)
  5. Exists Fail only when no contact information is found anywhere
  6. Reachable Pass if a contact page link or contact details appear in footer/nav
  7. Reachable Warn if contact is only reachable inside About page content, not directly in footer/nav
  8. Do not recommend creating /contact when About or footer already expose contact info — note the existing pathway instead

This is the start of the file. Read the full SKILL.md on GitHub.

Security

  • Security scanPassed, 95 of 100Pattern checks on the skill's files.
  • Model reviewPassed

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
532
Repository forks
69
7-day trend score
31

Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/jeffli1993/seo-audit-skill/seo-audit/badge)](https://verified-skill.com/skills/jeffli1993/seo-audit-skill/seo-audit)

Something wrong with this skill or its page? Tell us.