12# seo-audit-full — Advanced Full SEO Audit
13
14This skill runs a full single-page SEO audit from the seo-audit-full directory.
15It does not route to seo-audit when only a URL is provided.
16
17---
18
19## When to Use This Skill
20
21Use seo-audit-full when the user asks for:
22
23- "seo-audit-full"
24- "full SEO audit"
25- "advanced SEO audit"
26- "technical SEO audit"
27- "deep audit"
28- "comprehensive SEO review"
29- "audit everything"
30
31URL-only requests are valid. When external datasets are not supplied, run the
32full public-signal workflow and clearly note missing data sources in the report.
33
34---
35
36## Input Expected
37
38| Input | Required | Notes |
39|-------|----------|-------|
40| Page URL | Yes | The primary page to audit |
41| Primary keyword | Recommended | Improves content relevance scoring |
42| PageSpeed API key | Yes | Required for full audit PageSpeed checks. Ask at the start and do not run PageSpeed without it. |
43| Raw HTML or page content | Optional | Enables more accurate content checks when supplied |
44| GSC / crawl / analytics data | Optional | Include when supplied, otherwise mark unavailable |
45| Competitor benchmark data | Optional | Include when supplied |
46
47At the start of a full audit, ask the user for a PageSpeed Insights API key:
48
49```
50For PageSpeed checks, please provide a Google PageSpeed Insights API key.
51Get one here: https://developers.google.com/speed/docs/insights/v5/get-started
52Open "Acquiring and using an API key" → "Get a Key".
53If you do not provide one, I will stop before running the full audit because
54PageSpeed is a required full-audit module.
55```
56
57Do not run seo-audit-full PageSpeed checks without a PageSpeed API key supplied
58by --api-key, PAGESPEED_API_KEY, or GOOGLE_PAGESPEED_API_KEY. If the key is
59missing, stop and ask the user to configure it instead of rendering a full report
60with missing PageSpeed data.
61
62---
63
64## Architecture: Full = Core + Performance + Advanced
65
66```
67┌─────────────────────────────────────────────────────────────┐
68│ seo-audit-full Workflow │
69│ │
70│ Phase 1: Run core scripts (./scripts/) │
71│ ┌──────────────────────────────────────────────────────┐ │
72│ │ check-site.py → robots.txt, sitemap, 404, URL │ │
73│ │ check-page.py → title, H1, meta desc, slug │ │
74│ │ check-schema.py → JSON-LD validation │ │
75│ │ fetch-page.py → raw HTML for analysis │ │
76│ └──────────────────────────────────────────────────────┘ │
77│ ↓ │
78│ Phase 2: Run performance + full-only scripts (./scripts/) │
79│ ┌──────────────────────────────────────────────────────┐ │
80│ │ check-pagespeed.py → Lighthouse scores + metrics │ │
81│ │ check-social.py → OG Tags + Twitter Card │ │
82│ │ (more scripts added here as modules grow) │ │
83│ └──────────────────────────────────────────────────────┘ │
84│ ↓ │
85│ Phase 3: LLM-only advanced checks │
86│ ┌──────────────────────────────────────────────────────┐ │
87│ │ E-E-A-T content quality scoring │ │
88│ │ Duplicate content signals │ │
89│ │ Anchor text quality assessment │ │
90│ └──────────────────────────────────────────────────────┘ │
91└─────────────────────────────────────────────────────────────┘
92```
93
94---
95
96## Output
97
98Produce an **Advanced Full SEO Audit Report** by filling the template at
99[assets/report-template.html](assets/report-template.html),
100then **save it to a file — never print raw HTML to the terminal**.
101
102**File naming:** reports/<hostname>-<slug>-full-audit.html
103```
104https://example.com/blog/best-tools → reports/example-com-blog-best-tools-full-audit.html
105https://example.com/ → reports/example-com-full-audit.html
106```
107
108**After saving, tell the user:**
109```
110✅ Full Report saved → reports/example-com-full-audit.html
111 Open it now? (yes / no)
112```
113If yes → run: open reports/example-com-full-audit.html
114
115**Template placeholders** — fill each independently:
116
117| Placeholder | Content |
118|---|---|
119| {{summary_verdict}} | One sentence: total checks run, how many failed/warned/passed |
120| {{summary_critical_html}} | <li> per critical item, or <li class="summary-empty">None</li> |
121| {{summary_warnings_html}} | <li> per warning item, or <li class="summary-empty">None</li> |
122| {{summary_passing_html}} | <li> per passing check, or <li class="summary-empty">None</li> |
123| {{pagespeed_checks_html}} | Full PageSpeed module using check-pagespeed.py output |
124| {{site_checks_html}} | Site-level check tables |
125| {{eeat_checks_html}} | E-E-A-T trust page table |
126| {{page_checks_html}} | Page-level check tables, including full-only additions |
127| {{priority_actions_html}} | Ordered priority action list |
128| {{insights_html}} | Optional finding walkthrough cards |
129
130---
131
132## Scripts
133
134Run full scripts from this directory. All output is structured JSON — use it
135directly as evidence.
136
137**Dependencies:** pip install requests
138
139### Phase 1: Core scripts
140
141```bash
142# 1. site-level checks (robots.txt + sitemap.xml + 404 + URL canonicalization)
143python scripts/check-site.py https://example.com
144
145# 2. page-level checks (H1, title, meta description, canonical, URL slug)
146python scripts/check-page.py https://example.com --keyword "primary keyword"
147
148# 3. fetch raw HTML for downstream scripts
149python scripts/fetch-page.py https://example.com --output /tmp/page.html
150
151# 4. JSON-LD schema validation
152python scripts/check-schema.py --file /tmp/page.html
153```
154
155### Phase 2: Full-only scripts
156
157```bash
158# 5. PageSpeed / Lighthouse checks
159python scripts/check-pagespeed.py https://example.com --strategy mobile --timeout 180 --api-key "USER_PROVIDED_KEY"
160# If no key was provided, do not run this command. Ask the user to configure a PageSpeed API key first.
161
162# 6. Social tags: OG + Twitter Card validation
163python scripts/check-social.py --file /tmp/page.html
164# Or directly from URL:
165python scripts/check-social.py https://example.com
166```
167
168Each script exits with code 0 (all pass/warn) or 1 (any fail/error).
169
170PageSpeed can take 200 seconds. Use a 180-second timeout by default. If it
171still times out, mark the Page Speed module as error and state that the
172PageSpeed API timed out; do not treat that as confirmed page performance failure.
173If PageSpeed fails because Google returns a quota/API-key error after a key was
174provided, keep the audit running and render the PageSpeed module as error with
175this instruction:
176Get a PageSpeed API key at https://developers.google.com/speed/docs/insights/v5/get-started → "Acquiring and using an API key" → "Get a Key".
177
178---
179
180## Scope — Full Audit Check Whitelist
181
182Full runs its own core checks plus the full-only items marked ★ below.
183
184### Site-Level Checks (in {{site_checks_html}})
185
186Core checks:
187- Sitemap URL Inventory · Staging Subdomain Indexation · robots.txt · sitemap.xml · 404 Handling · URL Canonicalization · i18n / hreflang
188
189**Staging Subdomain Indexation rules:**
190- Check common staging/test hosts before robots.txt: test., staging., dev., preview., beta., uat.
191- **Fail** when a staging/test subdomain is publicly accessible, closely mirrors the production site, and is not protected by authentication, noindex, or a blocking robots.txt.
192- **Warn** when a staging/test subdomain is publicly accessible but similarity or index protection cannot be confirmed.
193- **Pass** when no public staging/test subdomain is detected, or detected staging hosts are protected by authentication, non-200 access, noindex, or Disallow: /.
194- Explain the impact as duplicate indexable pages: Google may treat test.example.com and www.example.com as separate but near-identical URLs, splitting ranking signals and competing with the production site.
195- Recommended fixes: add Basic Auth/password protection first; also block crawlers on the staging host with User-agent: * + Disallow: /; add page-level noindex if pages can still be accessed.
196
197**Sitemap URL Inventory rules:**
198- Place this as the first module in {{site_checks_html}}, before the Crawlability table.
199- Render it as its own table with columns: Directory · URL Count · Page Type · Example Page.
200- Use check-site.py sitemap_inventory output to summarize first-level directories, URL counts, inferred page types, and one representative example URL.
201- Treat this as a site-level map, not a pass/fail single-page SEO audit.
202- Use status info unless sitemap URLs cannot be parsed; do not penalize a site for having many or few URLs in a directory without deeper evidence.
203- Always include a next-step note: the user can continue with deeper full audits by selecting representative sample URLs from major directories such as /blog/, /tools/, /alternatives/, /templates/, or /use-cases/.
204
205### Page Speed Checks (in {{pagespeed_checks_html}})
206
207Full-only:
208- Lighthouse category scores: Performance · Accessibility · Best Practices · SEO
209- Lab metrics: FCP · LCP · TBT · CLS · Speed Index
210- Final URL and screenshot availability
211
212### E-E-A-T Checks (in {{eeat_checks_html}})
213
214Core checks:
215- About Us · Contact · Privacy Policy · Terms of Service · Media/Partners (only if present)
216
217Contact logic (Contact row only):
218- A dedicated /contact page is **not required**
219- **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
220- **Fail** only when no contact pathway exists anywhere on the site
221- Missing /contact alone is **not** a fail when About or footer/nav already expose contact info
222
223E-E-A-T infrastructure rules — two layers per trust page:
224- **Layer 1 — Exists:** HTTP 200 for the trust page URL (Contact uses Contact-specific rules above)
225- **Layer 2 — Reachable:** linked from footer or main nav
226
227| Page | Required |
228|---|---|
229| About Us | Yes |
230| Contact | Yes — dedicated page optional; About or footer/nav contact details satisfy this |
231| Privacy Policy | Yes |
232| Terms of Service | Yes |
233| Media / Partners | No — include only if present |
234
235Status rules (About, Privacy, Terms, Media/Partners):
236- Page missing (non-200) → **Fail**
237- Page exists but not linked in footer/nav → **Warn**
238- Page exists and linked in footer/nav → **Pass**
239- Optional page missing → skip, do not include row
240
241**Contact-specific rules:**
2421. Try common paths (/contact, /contact-us) — HTTP 200 counts as Exists
2432. If no contact page, check the About page body for email, social, or contact details
2443. Also scan homepage footer and nav for mailto:, visible email, social links, or a contact form
2454. **Exists Pass** if any contact pathway is found
2465. **Exists Fail** only when no contact information is found anywhere
2476. **Reachable Pass** if a contact page link or contact details appear in footer/nav
2487. **Reachable Warn** if contact is only reachable inside About page content, not directly in footer/nav
2498. Do not recommend creating /contact when About or footer already expose contact info
250
251### Page-Level Checks (in {{page_checks_html}}), output in this exact order:
252
253Core checks:
254URL Slug · Title Tag · Meta Description · H1 Tag · Canonical Tag · Image Alt Text ·
255Word Count · Keyword Placement · Heading Structure · Internal Links · Schema (JSON-LD)
256
257**Schema (JSON-LD) rules:**
258- Treat Schema as a quality check, not only a presence check.
259- Validate JSON-LD parseability, expected @type, required fields, recommended rich-result fields, nested fields, and primary-type conflicts.
260- **Fail** when JSON-LD is invalid, the expected schema type is missing, required fields are missing, or localized schema clearly points to the wrong language/URL.
261- **Warn** when recommended fields are missing, nested fields are incomplete, multilingual pages lack inLanguage, or localized schema cannot be fully confirmed.
262- **Pass** only when the expected schema type is present, required fields are present, no conflicts are found, and localized schema matches the current page language/URL when applicable.
263- For multilingual pages, each language version should have its own schema with matching inLanguage, language-specific headline/description where present, and url / mainEntityOfPage pointing to the current localized canonical URL.
264
265★ Full-only additions:
266- **OG Tags** — og:title, og:description, og:image, og:type, og:url presence and validity
267- **Twitter Card** — twitter:card type, title/description/image (with OG fallback detection)
268
269---
270
271## How to Use Script JSON Output
272
273Same rules across full audit modules — map each field's status directly to the report check table:
274- status → pass / warn / fail / error → badge in report
275- detail → starting point for Evidence line
276- Do not contradict script output unless you have additional observable evidence
277
278**For check-site.py output:**
279- staging_subdomains.status → Staging Subdomain Indexation row status
280- staging_subdomains.detail → Staging Subdomain Indexation row detail
281- staging_subdomains.public_hosts → evidence for public staging/test hosts
282- staging_subdomains.similar_hosts → fail evidence for production-like staging duplicates
283- robots.status → robots.txt row status
284- sitemap.status → sitemap.xml row status
285- sitemap_inventory.status → Sitemap URL Inventory module status
286- sitemap_inventory.directories[] → table rows with path, url_count, page_type, and example_url
287- sitemap_inventory.detail → short explanatory note below the inventory table
288
289**For check-schema.py output:**
290- status → Schema (JSON-LD) row status
291- detail → Schema (JSON-LD) row detail
292- parse_errors → fail evidence for malformed JSON-LD
293- schemas[].fields_missing → fail evidence for missing required schema fields
294- schemas[].recommended_missing and schemas[].nested_issues → warning evidence
295- localized_schema.status → language/URL alignment status for multilingual schema
296- localized_schema.issues → evidence for schema language or URL mismatch
297
298**For check-social.py output:**
299- og.status → OG Tags row status
300- twitter_card.status → Twitter Card row status
301- og.fields.* → individual field details for the detail cell
302- twitter_card.fields.* → individual field details, note fallback fields
303
304**For check-pagespeed.py output:**
305- status → overall Page Speed status
306- category_status → Lighthouse Scores badge status
307- metric_status → Core Lab Metrics badge status
308- final_url → Final URL line
309- categories.performance.score → Performance score
310- categories.accessibility.score → Accessibility score
311- categories["best-practices"].score → Best Practices score
312- categories.seo.score → SEO score
313- compact_metrics.fcp.display_value → FCP
314- compact_metrics.lcp.display_value → LCP
315- compact_metrics.tbt.display_value → TBT
316- compact_metrics.cls.display_value → CLS
317- compact_metrics.si.display_value → Speed Index
318- screenshot truthy → Screenshot available
319
320Do not use overall status for the Lighthouse Scores badge. Category scores use
321Lighthouse thresholds: 90–100 pass, 50–89 warn, 0–49 fail. Example: Performance
32260, Accessibility 84, Best Practices 100, SEO 100 means category_status is
323warn. If LCP or Speed Index fails, metric_status and overall status may be
324fail while the Lighthouse Scores panel remains warn.
325
326Inside {{pagespeed_checks_html}}, include a short Priority Actions list after
327the score/metric cards. Keep it to 2–4 concise items based on failing or warning
328PageSpeed fields:
329- LCP slow → optimize hero media, preload critical image, reduce render-blocking CSS
330- Speed Index slow → defer non-critical scripts and reduce above-the-fold JS/CSS
331- TBT high → split long tasks and delay third-party tags
332- Performance score warning/fail → prioritize the biggest Lighthouse opportunities
333
334Always include the official diagnostic link:
335https://pagespeed.web.dev/
336
337---
338
339## LLM Review Instructions
340
341### Core LLM reviews
342
343Resolve every llm_review_required: true field before writing the report:
344H1 semantic judgment, Title keyword position, URL Slug evaluation, and Meta
345Description quality must all receive an explicit judgment.
346
347### Full-only LLM checks
348
349**OG Tags quality (always review):**
350```
351og:title : Does it differ meaningfully from <title>? It should be optimized for social sharing.
352og:description : Is it compelling for social feeds? Different focus than meta description is OK.
353og:image : Is the URL an actual image path (not a page URL)?
354```
355
356**Twitter Card completeness:**
357```
358If twitter:card is "summary_large_image", twitter:image (or og:image fallback) must be
359at least 300x157px. Flag if the image URL looks like a small icon or favicon.
360```
361
362---
363
364## Recommended Workflow
365
3661. **Acknowledge full scope** — confirm this is a full audit
3672. **Infer primary keyword** — read the page H1, title, and first paragraph unless the user provided one
3683. **Phase 1: Run core scripts** — check-site → check-page → fetch-page → check-schema
3694. **Phase 2: Run full-only scripts** — verify PageSpeed API key exists, then run check-pagespeed → check-social
3705. **Core checks** — 404 handling, URL canonicalization, E-E-A-T trust pages, i18n/hreflang
3716. **PageSpeed checks** — summarize Lighthouse category scores and lab metrics
3727. **LLM-only advanced checks** — E-E-A-T content quality, duplicate content signals, anchor text quality
3738. **Summarize findings** — Evidence / Impact / Fix format
3749. **Priority actions** — top 5 highest-impact fixes with effort/impact tags
37510. **Render report** — save to reports/<hostname>-<slug>-full-audit.html
376
377---
378
379## Report Detail Writing Rules
380
381Use strict formatting:
382
383**Pass → one short phrase. No lists, no elaboration.**
384
385**Warn → one <div class="detail-issue"> with ≤2 bullet points. One <div class="detail-fix">.**
386
387**Fail → same as Warn. Lead with the exact failure.**
388
389---
390
391## Mandatory Finding Format
392
393```
394**Finding: [Finding Title]**
395
396- **Evidence:** [Observable fact, data point, or marked assumption]
397- **Impact:** [SEO / UX consequence]
398- **Fix:** [Actionable recommendation with example]
399```
400
401For Priority Actions, add effort/impact tags:
402```
4031. [High Impact / Low Effort] Fix og:image — social shares currently show no preview.
404```
405
406---
407
408## Reference Files
409
410- Detailed audit modules and field definitions: [references/REFERENCE.md](references/REFERENCE.md)
411- Final HTML report template: [assets/report-template.html](assets/report-template.html)
412- PageSpeed validation script: [scripts/check-pagespeed.py](scripts/check-pagespeed.py)
413- Social tags validation script: [scripts/check-social.py](scripts/check-social.py)
414- Core scripts: [scripts/](scripts/) (check-site, check-page, check-schema, fetch-page)
415