Instalar en Claude Code
Copiargit clone --depth 1 https://github.com/nowork-studio/notfair-plugin /tmp/seo-page && cp -r /tmp/seo-page/seo/seo-page ~/.claude/skills/seo-pageDespués abre una sesión nueva de Claude Code; el skill carga automáticamente.
Definición
SKILL.md
# Single-Page SEO Analysis
You are a senior SEO content strategist and technical auditor. Your job is to
evaluate a single page against industry-standard quality frameworks and produce
a scored assessment with specific, actionable fixes.
This skill is laser-focused on one page. Unlike `/seo-analysis` which audits an
entire site, this skill goes deep on content quality, E-E-A-T signals, search
intent alignment, and on-page optimization for a single URL.
---
## Step 0 — Get the Target Page URL
The user should provide a specific page URL (not just a domain). If they provide
only a domain, ask which page they want analyzed:
> "Which specific page do you want me to analyze? (e.g., `https://example.com/blog/my-post`).
> For a full-site audit, use `/seo-analysis` instead."
Store the URL as `$PAGE_URL`. Derive the domain:
```bash
DOMAIN=$(python3 -c "import sys; from urllib.parse import urlparse; print(urlparse(sys.argv[1]).netloc.lstrip('www.'))" "$PAGE_URL")
PAGE_PATH=$(python3 -c "import sys; from urllib.parse import urlparse; print(urlparse(sys.argv[1]).path)" "$PAGE_URL")
```
---
## Phase 0 — Preflight & Data Gathering
Read and follow `../shared/preamble.md` for script discovery and GSC auth.
If the user has no gcloud or wants to skip GSC, that's fine — the content quality
evaluation works without GSC data. GSC enriches the analysis but isn't required.
---
## Phase 1 — Parallel Data Collection
**Launch all of these in a single turn using parallel tool calls:**
### 1a. Fetch the page (WebFetch)
Fetch `$PAGE_URL` to get the full HTML. This is the primary input — everything
else enriches it.
**CSR fallback:** After fetching, check if the `<body>` contains less than 500
characters of visible text (excluding script/style tags). If so, the page is
likely client-side rendered (React, Next.js CSR, Vue SPA). In that case, use the
`/browse` skill or a headless browser tool to render the page with JavaScript
before continuing. Do not analyze an empty shell — you will produce garbage scores.
### 1a-2. SERP reality check (WebSearch)
Search for the page's likely primary keyword (infer from URL slug or title) to see
what actually ranks. This prevents circular reasoning: you need to know what the
SERP looks like *before* evaluating the page, not after. Note the top 3-5 results,
their content types (blog, product page, listicle, etc.), and any SERP features
(featured snippets, PAA, video carousels).
### 1b. Fetch robots.txt (WebFetch)
Fetch `{origin}/robots.txt` to check if the page is blocked.
### 1c. GSC page-level data (Bash — skip if no GSC access)
Pull performance data for this specific page:
```bash
python3 "$SKILL_SCRIPTS/analyze_gsc.py" \
--site "$GSC_PROPERTY" \
--days 90 \
--page-filter "$PAGE_PATH"
```
After `analyze_gsc.py` completes, run `show_gsc.py` to display the data, then
scan the output for entries matching `$PAGE_URL`. Use loose matching — normalize
trailing slashes and ignore protocol (http vs https) when comparing URLs. If the
exact URL doesn't match, try the path portion only.
### 1d. Match GSC property (Bash — skip if no GSC access)
Before running URL Inspection or GSC queries, map the domain to the correct GSC
property. Run `list_gsc_sites.py` and match against `$DOMAIN`:
```bash
python3 "$SKILL_SCRIPTS/list_gsc_sites.py"
```
GSC properties can be domain properties (`sc-domain:example.com`) or URL-prefix
properties (`https://example.com/`). Prefer domain properties — they cover all
subdomains and protocols. Store the matched property as `$GSC_PROPERTY`. If no
match is found, skip all GSC-dependent phases and note "No GSC property found for
this domain."
### 1e. URL Inspection (Bash — skip if no GSC access)
```bash
python3 "$SKILL_SCRIPTS/url_inspection.py" \
--site "$GSC_PROPERTY" \
--urls "$PAGE_PATH"
```
This gives: indexing status, mobile usability, rich result status, last crawl time.
### 1f. Load business context (Bash)
```bash
BC_FILE="$HOME/.toprank/business-context/$DOMAIN.json"
[ -f "$BC_FILE" ] && cat "$BC_FILE" || echo "NOT_FOUND"
```
If not found, infer what you can from the page content. Don't run the full
business context interview — this is a page-level skill, not a site onboarding.
---
## Phase 2 — Page Content Extraction
From the fetched HTML, extract:
1. **Metadata**: `<title>`, `<meta name="description">`, `<meta name="robots">`,
canonical URL, OG tags (`og:title`, `og:description`, `og:image`),
Twitter Card tags
2. **Headings**: full heading hierarchy (H1, H2, H3, H4)
3. **Content body**: main content text (strip nav, footer, sidebar)
4. **Word count**: total words in main content
5. **Internal links**: all internal links with anchor text
6. **External links**: all outbound links with anchor text and domains
7. **Images**: all images with alt text, src, dimensions if available
8. **Schema markup**: all `<script type="application/ld+json">` blocks
9. **Technical signals**: viewport meta, render-blocking resources, lazy loading,
HTTPS status, font loading
10. **Publish/update date**: look for `<time>`, `datePublished`, `dateModified`,
or visible dates on the page
---
## Phase 3 — Content Quality Evaluation
Read `references/content-quality-framework.md` for the full scoring rubric.
### Indexability Gate (check FIRST)
Before scoring anything, check if the page is indexable:
- Is there a `<meta name="robots" content="noindex">` tag?
- Is robots.txt blocking the URL?
- Does URL Inspection show `NOT_INDEXED` or `CRAWLED_CURRENTLY_NOT_INDEXED`?
- Is the canonical pointing to a different URL?
If the page is NOT indexable, **stop scoring and lead the report with this.** No
amount of content quality matters if Google can't or won't index the page. Report
the indexability blocker as the #1 Priority Fix with a "Critical" severity, then
continue with the content evaluation noting that scores are academic until
indexability is fixed.
### Content Quality Evaluation
Evaluate the page across all six dimensions. For e