# Seo Audit Full

> >-

- **Type:** Skill
- **Install:** `agentstack add skill-jeffli1993-seo-audit-skill-seo-audit-full`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [JeffLi1993](https://agentstack.voostack.com/s/jeffli1993)
- **Installs:** 0
- **Category:** [Agent Skills](https://agentstack.voostack.com/c/agent-skills)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [JeffLi1993](https://github.com/JeffLi1993)
- **Source:** https://github.com/JeffLi1993/seo-audit-skill/tree/main/seo-audit-full
- **Website:** https://nanoskill.ai/skills/seo-audit

## Install

```sh
agentstack add skill-jeffli1993-seo-audit-skill-seo-audit-full
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# seo-audit-full — Advanced Full SEO Audit

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.

---

## When to Use This Skill

Use `seo-audit-full` when the user asks for:

- "seo-audit-full"
- "full SEO audit"
- "advanced SEO audit"
- "technical SEO audit"
- "deep audit"
- "comprehensive SEO review"
- "audit everything"

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 Expected

| 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.

---

## Architecture: Full = Core + Performance + Advanced

```
┌─────────────────────────────────────────────────────────────┐
│  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                       │   │
│  └──────────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────────┘
```

---

## Output

Produce an **Advanced Full 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/--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}}` | `` per critical item, or `None` |
| `{{summary_warnings_html}}` | `` per warning item, or `None` |
| `{{summary_passing_html}}` | `` per passing check, or `None` |
| `{{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 |

---

## Scripts

Run full scripts from this directory. All output is structured JSON — use it
directly as evidence.

**Dependencies:** `pip install requests`

### Phase 1: Core scripts

```bash
# 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
```

### Phase 2: Full-only scripts

```bash
# 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".`

---

## Scope — Full Audit Check Whitelist

Full runs its own core checks plus the full-only items marked ★ below.

### Site-Level Checks (in `{{site_checks_html}}`)

Core checks:
- Sitemap URL Inventory · Staging Subdomain Indexation · robots.txt · sitemap.xml · 404 Handling · URL Canonicalization · i18n / hreflang

**Staging Subdomain Indexation rules:**
- Check common staging/test hosts before robots.txt: `test.`, `staging.`, `dev.`, `preview.`, `beta.`, `uat.`
- **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`.
- **Warn** when a staging/test subdomain is publicly accessible but similarity or index protection cannot be confirmed.
- **Pass** when no public staging/test subdomain is detected, or detected staging hosts are protected by authentication, non-200 access, `noindex`, or `Disallow: /`.
- 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.
- 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.

**Sitemap URL Inventory rules:**
- Place this as the first module in `{{site_checks_html}}`, before the Crawlability table.
- Render it as its own table with columns: Directory · URL Count · Page Type · Example Page.
- Use `check-site.py` `sitemap_inventory` output to summarize first-level directories, URL counts, inferred page types, and one representative example URL.
- Treat this as a site-level map, not a pass/fail single-page SEO audit.
- 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.
- 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/`.

### Page Speed Checks (in `{{pagespeed_checks_html}}`)

Full-only:
- Lighthouse category scores: Performance · Accessibility · Best Practices · SEO
- Lab metrics: FCP · LCP · TBT · CLS · Speed Index
- Final URL and screenshot availability

### E-E-A-T Checks (in `{{eeat_checks_html}}`)

Core checks:
- 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

E-E-A-T infrastructure rules — two layers per trust page:
- **Layer 1 — Exists:** HTTP 200 for the trust page URL (Contact uses Contact-specific rules above)
- **Layer 2 — Reachable:** linked from footer or main nav

| 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):
- 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:**
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
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

### Page-Level Checks (in `{{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:**
- Treat Schema as a quality check, not only a presence check.
- Validate JSON-LD parseability, expected `@type`, required fields, recommended rich-result fields, nested fields, and primary-type conflicts.
- **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.
- **Warn** when recommended fields are missing, nested fields are incomplete, multilingual pages lack `inLanguage`, or localized schema cannot be fully confirmed.
- **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.
- 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.

★ Full-only additions:
- **OG Tags** — og:title, og:description, og:image, og:type, og:url presence and validity
- **Twitter Card** — twitter:card type, title/description/image (with OG fallback detection)

---

## How to Use Script JSON Output

Same rules across full audit modules — map each field's `status` directly to the report check table:
- `status` → `pass` / `warn` / `fail` / `error` → badge in report
- `detail` → starting point for Evidence line
- Do not contradict script output unless you have additional observable evidence

**For `check-site.py` output:**
- `staging_subdomains.status` → Staging Subdomain Indexation row status
- `staging_subdomains.detail` → Staging Subdomain Indexation row detail
- `staging_subdomains.public_hosts` → evidence for public staging/test hosts
- `staging_subdomains.similar_hosts` → fail evidence for production-like staging duplicates
- `robots.status` → robots.txt row status
- `sitemap.status` → sitemap.xml row status
- `sitemap_inventory.status` → Sitemap URL Inventory module status
- `sitemap_inventory.directories[]` → table rows with `path`, `url_count`, `page_type`, and `example_url`
- `sitemap_inventory.detail` → short explanatory note below the inventory table

**For `check-schema.py` output:**
- `status` → Schema (JSON-LD) row status
- `detail` → Schema (JSON-LD) row detail
- `parse_errors` → fail evidence for malformed JSON-LD
- `schemas[].fields_missing` → fail evidence for missing required schema fields
- `schemas[].recommended_missing` and `schemas[].nested_issues` → warning evidence
- `localized_schema.status` → language/URL alignment status for multilingual schema
- `localized_schema.issues` → evidence for schema language or URL mismatch

**For `check-social.py` output:**
- `og.status` → OG Tags row status
- `twitter_card.status` → Twitter Card row status
- `og.fields.*` → individual field details for the detail cell
- `twitter_card.fields.*` → individual field details, note fallback fields

**For `check-pagespeed.py` output:**
- `status` → overall Page Speed status
- `category_status` → Lighthouse Scores badge status
- `metric_status` → Core Lab Metrics badge status
- `final_url` → Final URL line
- `categories.performance.score` → Performance score
- `categories.accessibility.score` → Accessibility score
- `categories["best-practices"].score` → Best Practices score
- `categories.seo.score` → SEO score
- `compact_metrics.fcp.display_value` → FCP
- `compact_metrics.lcp.display_value` → LCP
- `compact_metrics.tbt.display_value` → TBT
- `compact_metrics.cls.display_value` → CLS
- `compact_metrics.si.display_value` → Speed Index
- `screenshot` truthy → Screenshot available

Do 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:
- LCP slow → optimize hero media, preload critical image, reduce render-blocking CSS
- Speed Index slow → defer non-critical scripts and reduce above-the-fold JS/CSS
- TBT high → split long tasks and delay third-party tags
- Performance score warning/fail → prioritize the biggest Lighthouse opportunities

Always include the official diagnostic link:
`https://pagespeed.web.dev/`

---

## LLM Review Instructions

### Core

…

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [JeffLi1993](https://github.com/JeffLi1993)
- **Source:** [JeffLi1993/seo-audit-skill](https://github.com/JeffLi1993/seo-audit-skill)
- **License:** MIT
- **Homepage:** https://nanoskill.ai/skills/seo-audit

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-jeffli1993-seo-audit-skill-seo-audit-full
- Seller: https://agentstack.voostack.com/s/jeffli1993
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
