seo-audit
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. I
By jeffli1993 · 436 installs
npx skills add jeffli1993/seo-audit-skill --skill seo-audit
Source repository · Upstream listing
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
Input Required Notes
Page URL Yes The page to audit
Raw HTML or page content Optional Enables more accurate on page analysis
GSC / analytics data Optional Not 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](assets/report template.html),
then save it to a file — never print raw HTML to the terminal .
File naming: reports/<hostname <slug audit.html
After saving, tell the user:
If yes → run: open reports/example com 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 (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)
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" :
Title — triggered when keyword match == "partial" OR keyword position != "start" :
URL Slug — triggered when keyword match != "full" or is homepage == false :
Meta Description — always triggered when content is present:
Recommended Workflow
Follow these steps in order:
1. Acknowledge scope — confirm this is a basic audit; note any missing data
2. 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 "
3. 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.
4. 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
Page Required
About Us Yes
Contact Yes — see Contact specific rules below
Privacy Policy Yes
Terms of Service Yes
Media / Partners No — 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
5. Run check page.py keyword "<inferred keyword " — parse the JSON output for H1, title,
meta description, canonical, and URL slug
6. i18n / hreflang check — only run if the page contains hreflang tags or <html lang suggests multi language:
Skip entirely (N/A) if no hreflang tags found and site appears single language
If hreflang tags present, check:
Reciprocal symmetry : every URL referenced must link back to all other variants — any broken link = Fail
Language codes : must be valid BCP 47 (e.g. zh CN not zh , en US not en us ) — wrong code = Warn
x default : should be present for language selector or fallback pages — missing = Warn
html[lang] attribute : must match the primary hreflang of the page — mismatch = Warn
URL structure : recommended pattern — default language (usually en ) at root with no prefix,
other languages under subpaths ( /zh/ , /es/ ).
/page (en) + /zh/page + /es/page → Pass
/en/page + /zh/page → Warn (en prefix is redundant, wastes crawl depth)
Only flag if the pattern is clearly inconsistent or en is unnecessarily prefixed
7. Run check schema.py — parse the JSON output for schema types and field validation
The script extracts JSON LD blocks, validates @type and required fields per Schema.org spec.
llm review required: true is always set — confirm inferred page type matches actual page content.
Page type → expected @type reference:
Page Type Expected @type Min. required fields
Homepage WebSite + Organization name, url, logo
Blog / Article Article or BlogPosting headline, datePublished, author, image
Product Product name, image, offers (price, priceCurrency)
FAQ FAQPage mainEntity[].name, acceptedAnswer.text
How to HowTo name, step[].text
Local business LocalBusiness name, address, telephone
Generic landing — N/A — skip, no widely supported type
Pass: correct @type present, all required fields valid, no conflicts
Warn: @type present but missing recommended fields
Fail: expected @type missing entirely
N/A: generic landing page — do not penalize
8. Summarize findings — each finding must follow the Evidence / Impact / Fix format
9. Priority actions — list the top 3 highest impact fixes
10. Render report — save to reports/<hostname <slug audit.html , then ask user to open
11. Upgrade prompt — if issues beyond basic scope are found, suggest seo audit full
Report Detail Writing Rules
The Detail cell in check tables must follow these rules — no exceptions:
Pass → one short phrase. No lists, no elaboration.
Warn → one <div class="detail issue" with ≤2 bullet points. One <div class="detail fix" with the fix.
Fail → same as Warn. Lead with the exact failure. No background explanations.
Do NOT explain what a check is, do NOT repeat information already visible in the status badge,
do NOT treat the reader as unfamiliar with SEO basics.
Mandatory Finding Format
Every important finding must follow this structure:
Do not write vague conclusions. If evidence is insufficient, state assumptions explicitly.
Upgrade Prompt
Include this at the end of every basic audit report:
Want a deeper analysis?
This was a basic SEO audit covering site level signals and core on page checks.
For advanced technical SEO, content quality scoring, structured data analysis, and full crawl based findings, use the seo audit full skill.
Reference Files
Detailed audit scope and field definitions: [references/REFERENCE.md](references/REFERENCE.md)
Final HTML report template: [assets/re