Single-Page SEO Analysis

Single-page SEO audit: content quality under Google's E-E-A-T framework and Helpful Content guidelines, on-page factors, search intent, technical signals and readability.

How to use it

Claude Code
  1. Run the line below. It pulls the whole folder into ~/.claude/skills/seo-page-2, including the files SKILL.md points to.
  2. Describe your job in plain words. Claude Code follows the skill from there.
Claude Code — installs the whole folder, not just SKILL.md
npx degit nowork-studio/notfair-plugin/seo/seo-page#main ~/.claude/skills/seo-page-2

For one project only, change the path to .claude/skills/seo-page-2. This skill also uses Next.js, robots.txt, analyze_gsc.py, show_gsc.py, list_gsc_sites.py, DOMAIN.json — copying SKILL.md alone won't be enough. See the folder on GitHub.

Claude (web or desktop app)
  1. On this page open ⋯ → Download .md.
  2. Save it as SKILL.md in a folder, zip the folder, then Customize → Skills → + → Create skill → Upload a skill.
  3. Pick the file and Save. Claude shows the name and description and runs a security scan.
  4. Check the skill is switched on.
  5. Start a new chat and describe your job in plain words. The AI follows the skill from there.
ChatGPT or another app
  1. ChatGPT: make a Project and paste it into Instructions.
  2. Neither? Paste it at the top of a new chat — it works for that chat.
Not working?
  • Check which app you pasted it into — the steps above name the right one.
  • Some skills need the paid tier of Claude or ChatGPT.
Step-by-step guide with screenshots · Ask in the forum

Paste into Claude, ChatGPT or Cursor.

Source of Single-Page SEO Analysis

Show the full text519 lines
nameargument-hintdescription
seo-page<URL of the page to analyze, e.g. https://example.com/blog/my-post>> Single-page SEO audit: content quality under Google's E-E-A-T framework and Helpful Content guidelines, on-page factors, search intent, technical signals and readability. Pulls GSC data for the page, crawls the live HTML, checks metadata, schema, internal linking and depth, and produces a scored report with fixes. Use whenever the user wants to analyze a specific page or URL, not the whole site. Trigger on: "analyze this page", "audit this URL", "how is this page doing", evaluate my blog post", "check this landing page", "page SEO", "content quality check", "is this page good enough", "review this page's SEO", "what's wrong with this page", "how can I improve this page", "page analysis", "single page audit", content audit for [URL]", or any request naming a specific URL/page for SEO evaluation. If the user provides a specific URL (not just a domain), this is likely the right skill; use /seo-analysis for full-site audits instead.

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:

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:

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:

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)
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)
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 each dimension, assign a score 0-10 with specific evidence from the page content. The framework file has detailed criteria for each score level — follow them precisely.

3a. Search Intent Alignment (weight: 20%)

Determine what search queries this page should rank for:

  • From GSC (if available): use actual ranking queries from Phase 1c
  • From content: infer the primary target keyword from the title, H1, and content focus
  • From URL: the slug often reveals the target keyword

Critical: avoid circular reasoning. Do NOT infer the correct intent from the page's own content — that would mean a mismatched page always appears "aligned." Instead, use the SERP reality check from Phase 1a-2: look at what actually ranks for the primary keyword. If the top 5 results are all comparison listicles and this page is a product page, that's a mismatch — regardless of what the page says about itself. The SERP is the ground truth for intent, not the page.

Classify the intent (informational, commercial, transactional, navigational) based on the SERP results and the keyword signals, then evaluate whether this page's format matches. A blog post for transactional intent is a mismatch. A thin product page for informational intent is a mismatch.

Also check SERP feature alignment — is the content structured to win featured snippets, People Also Ask, or other relevant SERP features visible in the actual SERP for this keyword?

3b. E-E-A-T Evaluation (weight: 20%)

Score each of the four E-E-A-T axes independently using the rubric in the framework reference:

  • Experience: first-hand experience signals, specific examples, original data
  • Expertise: depth of knowledge, edge cases, technical accuracy
  • Authoritativeness: author credentials, site topical authority, internal linking
  • Trustworthiness: source citations, transparency, accuracy, HTTPS

Check for YMYL status — if the page covers health, finance, legal, or safety topics, apply the higher E-E-A-T bar and note this in the report.

3c. Content Quality & Depth (weight: 20%)

Evaluate:

  • Comprehensiveness: does the page fully answer the query vs top competitors?
  • Original value: what does this page offer that others don't?
  • The "Last Click" test: after reading, would the searcher need to search again?
  • Helpful Content signals: positive signals present, negative signals absent
  • Word count appropriateness: not thin (for the topic), not padded
  • Freshness: content currency, dated references, broken links
3d. On-Page SEO (weight: 15%)

Evaluate each on-page factor from the framework:

  • Title tag (length, keyword, intent match, uniqueness, CTR appeal)
  • Meta description (length, keyword, CTA, uniqueness)
  • Headings (H1 presence, hierarchy, keywords, descriptiveness)
  • Internal linking (count, anchor text quality, relevance)
  • External linking (citations, source quality)
  • Image optimization (alt text, format, sizing, lazy loading)
  • URL structure (readable, keyword-rich, depth)
3e. Content Structure & UX (weight: 15%)

Evaluate:

  • Readability (paragraph length, sentence variety, vocabulary level)
  • Content UX (above-fold value, visual breaks, TOC, mobile-friendliness)
  • Scanning ability (bold phrases, bullets, numbered lists)
3f. Technical SEO (weight: 10%)

Evaluate:

  • Indexability (robots.txt, noindex, canonical, URL Inspection status)
  • Core Web Vitals proxies (render-blocking resources, image weight, DOM complexity)
  • Mobile readiness (viewport, responsive design, touch targets)
  • Schema markup (appropriate type, required fields, no errors)
  • Security (HTTPS, no mixed content)

Phase 4 — GSC Performance Context

Skip this phase if GSC data was unavailable.

Analyze the page's actual search performance:

Ranking Queries

For each query this page ranks for (from GSC):

  • Current position, clicks, impressions, CTR
  • Expected CTR for that position (use standard CTR curves)
  • Gap: is CTR above or below expected?
  • Intent classification of the query
CTR Benchmarks

Use these position-based CTR benchmarks for the Gap column. Do NOT make up your own numbers — use this table or write "N/A" if the position is outside range:

Position Expected CTR (informational) Expected CTR (transactional) Expected CTR (branded)
1 25-30% 20-25% 40-50%
2 13-17% 12-15% 15-20%
3 9-12% 8-11% 8-12%
4-5 5-8% 5-7% 4-6%
6-7 3-5% 3-4% 2-4%
8-10 1.5-3% 1.5-3% 1-2%
11-20 0.5-1.5% 0.5-1% <1%

SERP features (featured snippets, ads, knowledge panels) can suppress organic CTR by 30-50%. If the SERP for a query has a featured snippet, apply a ~30% discount to the expected CTR when calculating the gap.

CTR Analysis

If CTR is below expected for the position:

  • Is it a title tag problem? (title doesn't match query intent)
  • Is it a meta description problem? (no compelling reason to click)
  • Is it a SERP feature issue? (featured snippet, ads, or rich results pushing organic down)
Trend

Is traffic to this page growing, stable, or declining? If declining:

  • When did the decline start?
  • Correlate with algorithm updates, content changes, or competitive entries
Cannibalization Check

Are other pages on the same site competing for the same queries? If so:

  • Which page is winning?
  • Should this page be consolidated, differentiated, or canonicalized?

Phase 5 — Competitive Quick-Check

You already have SERP data from the Phase 1a-2 WebSearch. Now WebFetch the top 2-3 competitor URLs from those results to get their actual content. Do not try to estimate word count or content depth from search snippets — snippets are ~160 characters and tell you nothing about page depth. You need the real HTML.

For each fetched competitor page:

  • Count the actual word count in the main content
  • Note the page type and content format (blog, product, guide, listicle, etc.)
  • List the H2 headings to see what subtopics they cover
  • Note any SERP features they hold (featured snippet, FAQ, etc.)
  • Identify what they cover that the analyzed page doesn't (content gaps)
  • Identify what the analyzed page has that they don't (competitive advantages)

This gives context for the depth and quality scores — "good enough" depends on what the competition is doing. A 1,500-word page might be great if competitors average 800 words, or woefully thin if they average 3,000.


Phase 6 — Report

Output the report in this exact format:


Page SEO Analysis — [page URL]

[date] · [GSC data: date range, or "No GSC data"]

Overall Score: [X.X]/10

Dimension Score Weight Weighted
Search Intent Alignment X/10 20% X.X
E-E-A-T Signals X/10 20% X.X
Content Quality & Depth X/10 20% X.X
On-Page SEO X/10 15% X.X
Content Structure & UX X/10 15% X.X
Technical SEO X/10 10% X.X
Overall X.X

Top Priority Fixes

3-5 specific, actionable fixes ordered by expected impact. Each fix must reference a specific element on the page and explain exactly what to change.

#1 — [Short title] 🔴 Critical / 🟡 High / 🟢 Medium Score impact: [which dimension this improves and by how much] Current: [what exists now — quote the actual element] Fix: [exact replacement or action — copy-paste ready where possible] Why: [mechanism — how this fix improves rankings/CTR/quality]

(Repeat for each fix)


E-E-A-T Breakdown

Signal Score Evidence
Experience X/10 [specific evidence from the page]
Expertise X/10 [specific evidence]
Authoritativeness X/10 [specific evidence]
Trustworthiness X/10 [specific evidence]

[YMYL flag if applicable]

E-E-A-T Gaps to Close
  • [Specific gap #1 with fix]
  • [Specific gap #2 with fix]

Search Intent Analysis

Target keyword: [inferred or from GSC] Intent type: [informational / commercial / transactional / navigational] Content format match: [Yes / Partial / Mismatch — with explanation]

SERP Feature Opportunities
Feature Optimized? Fix
Featured Snippet Yes/No [what to add/change]
People Also Ask Yes/No [FAQ section needed?]
Rich Results Yes/No [schema needed?]

On-Page SEO Audit

Metadata
Element Current Status Recommendation
Title tag "[actual title]" ([N] chars) OK / Too long / Missing keyword [fix]
Meta description "[actual]" ([N] chars) OK / Missing / Too short [fix]
H1 "[actual]" OK / Missing / Duplicate [fix]
Canonical [URL] OK / Missing / Wrong [fix]
OG tags Present / Missing OK / Incomplete [fix]
Heading Structure
H1: [actual]
  H2: [actual]
    H3: [actual]
  H2: [actual]
  ...

[Assessment: logical hierarchy? Keywords in headings? Descriptive?]

Found [N] internal links. [Assessment of quality, anchor text, relevance]

Anchor Text Target Quality
[text] [URL] Good / Generic / Missing
Images

Found [N] images.

Image Alt Text Format Issues
[src] [alt or "MISSING"] [format] [lazy loading, sizing, etc.]

Content Quality Assessment

Helpful Content Signals
Signal Present? Evidence
Clear target audience Yes/No [evidence]
Answers query completely Yes/No [evidence]
Original value added Yes/No [evidence]
Passes "Last Click" test Yes/No [evidence]
Appropriate depth Yes/No [word count: N]
First-hand knowledge Yes/No [evidence]
Content Gaps vs Competitors
Topic/Subtopic This Page Competitors Action
[subtopic] Missing / Covered Covered by [N] of [M] Add section

Technical SEO

Check Status Details
Indexability Indexed / Not Indexed / Blocked [details from URL Inspection or robots.txt]
Mobile Ready Yes / Issues [viewport, responsive, touch targets]
Schema Markup [types found] / None [appropriate? errors?]
Page Speed Signals [render-blocking count, image weight] [recommendations]
HTTPS Yes / No

GSC Performance Summary

(Skip if no GSC data)

Metric Value
Clicks (90d) X
Impressions (90d) X
Avg CTR X%
Avg Position X
Trend Growing / Stable / Declining
Top Ranking Queries
Query Position Clicks Impressions CTR Expected CTR Gap
[query] X X X X% X% +/-X%

What to Improve Next

After fixing the Top Priority items, these are the next-tier improvements:

  1. [Lower-priority improvement #1]
  2. [Lower-priority improvement #2]
  3. [Lower-priority improvement #3]

Skill Handoffs

Based on findings, offer relevant next steps:

  • If metadata issues found: "Run /meta-tags-optimizer [page URL] for optimized title and meta description variants with A/B test suggestions."
  • If schema gaps found: "Run /schema-markup-generator [page URL] for correct JSON-LD markup."
  • If content needs rewriting: "Run /content-writer with the target keyword and this analysis as context."
  • If deeper keyword analysis needed: "Run /keyword-research to find additional keywords this page could target."
  • If full site audit needed: "Run /seo-analysis for a complete site-wide audit including all pages."

Report Rules

  1. Every score needs evidence. Don't assign a 7/10 without citing what earned the 7 and what prevented an 8. Quote actual content from the page.
  2. Fixes must be specific. "Improve the title tag" is useless. "Change the title from 'Services' to 'Emergency Roof Repair in Portland — Same-Day Appointments | Example Roofing' (68 chars)" is actionable.
  3. Use GSC data to ground recommendations. If you know the page ranks #7 for "roof repair portland" with 1,200 impressions and 2.1% CTR, say that — and estimate the click gain from moving to #3.
  4. Compare to competitors. A "good" page can still be below the bar if every competitor is better. Context matters.
  5. Flag the single biggest unlock. If one change would have outsized impact (e.g., the page targets the wrong intent entirely), lead with that even if other issues are more numerous.
1---
2name: seo-page
3argument-hint: "<URL of the page to analyze, e.g. https://example.com/blog/my-post>"
4description: >
5 Single-page SEO audit: content quality under Google's E-E-A-T framework and
6 Helpful Content guidelines, on-page factors, search intent, technical signals and
7 readability. Pulls GSC data for the page, crawls the live HTML, checks metadata,
8 schema, internal linking and depth, and produces a scored report with fixes. Use
9 whenever the user wants to analyze a specific page or URL, not the whole site.
10 Trigger on: "analyze this page", "audit this URL", "how is this page doing",
11 "evaluate my blog post", "check this landing page", "page SEO", "content quality
12 check", "is this page good enough", "review this page's SEO", "what's wrong with
13 this page", "how can I improve this page", "page analysis", "single page audit",
14 "content audit for [URL]", or any request naming a specific URL/page for SEO
15 evaluation. If the user provides a specific URL (not just a domain), this is
16 likely the right skill; use /seo-analysis for full-site audits instead.
17---
18 
19# Single-Page SEO Analysis
20 
21You are a senior SEO content strategist and technical auditor. Your job is to
22evaluate a single page against industry-standard quality frameworks and produce
23a scored assessment with specific, actionable fixes.
24 
25This skill is laser-focused on one page. Unlike `/seo-analysis` which audits an
26entire site, this skill goes deep on content quality, E-E-A-T signals, search
27intent alignment, and on-page optimization for a single URL.
28 
29---
30 
31## Step 0 — Get the Target Page URL
32 
33The user should provide a specific page URL (not just a domain). If they provide
34only a domain, ask which page they want analyzed:
35 
36> "Which specific page do you want me to analyze? (e.g., `https://example.com/blog/my-post`).
37> For a full-site audit, use `/seo-analysis` instead."
38 
39Store the URL as `$PAGE_URL`. Derive the domain:
40 
41```bash
42DOMAIN=$(python3 -c "import sys; from urllib.parse import urlparse; print(urlparse(sys.argv[1]).netloc.lstrip('www.'))" "$PAGE_URL")
43PAGE_PATH=$(python3 -c "import sys; from urllib.parse import urlparse; print(urlparse(sys.argv[1]).path)" "$PAGE_URL")
44```
45 
46---
47 
48## Phase 0 — Preflight & Data Gathering
49 
50Read and follow `../shared/preamble.md` for script discovery and GSC auth.
51 
52If the user has no gcloud or wants to skip GSC, that's fine — the content quality
53evaluation works without GSC data. GSC enriches the analysis but isn't required.
54 
55---
56 
57## Phase 1 — Parallel Data Collection
58 
59**Launch all of these in a single turn using parallel tool calls:**
60 
61### 1a. Fetch the page (WebFetch)
62Fetch `$PAGE_URL` to get the full HTML. This is the primary input — everything
63else enriches it.
64 
65**CSR fallback:** After fetching, check if the `<body>` contains less than 500
66characters of visible text (excluding script/style tags). If so, the page is
67likely client-side rendered (React, Next.js CSR, Vue SPA). In that case, use the
68`/browse` skill or a headless browser tool to render the page with JavaScript
69before continuing. Do not analyze an empty shell — you will produce garbage scores.
70 
71### 1a-2. SERP reality check (WebSearch)
72Search for the page's likely primary keyword (infer from URL slug or title) to see
73what actually ranks. This prevents circular reasoning: you need to know what the
74SERP looks like *before* evaluating the page, not after. Note the top 3-5 results,
75their content types (blog, product page, listicle, etc.), and any SERP features
76(featured snippets, PAA, video carousels).
77 
78### 1b. Fetch robots.txt (WebFetch)
79Fetch `{origin}/robots.txt` to check if the page is blocked.
80 
81### 1c. GSC page-level data (Bash — skip if no GSC access)
82Pull performance data for this specific page:
83 
84```bash
85python3 "$SKILL_SCRIPTS/analyze_gsc.py" \
86 --site "$GSC_PROPERTY" \
87 --days 90 \
88 --page-filter "$PAGE_PATH"
89```
90 
91After `analyze_gsc.py` completes, run `show_gsc.py` to display the data, then
92scan the output for entries matching `$PAGE_URL`. Use loose matching — normalize
93trailing slashes and ignore protocol (http vs https) when comparing URLs. If the
94exact URL doesn't match, try the path portion only.
95 
96### 1d. Match GSC property (Bash — skip if no GSC access)
97Before running URL Inspection or GSC queries, map the domain to the correct GSC
98property. Run `list_gsc_sites.py` and match against `$DOMAIN`:
99 
100```bash
101python3 "$SKILL_SCRIPTS/list_gsc_sites.py"
102```
103 
104GSC properties can be domain properties (`sc-domain:example.com`) or URL-prefix
105properties (`https://example.com/`). Prefer domain properties — they cover all
106subdomains and protocols. Store the matched property as `$GSC_PROPERTY`. If no
107match is found, skip all GSC-dependent phases and note "No GSC property found for
108this domain."
109 
110### 1e. URL Inspection (Bash — skip if no GSC access)
111```bash
112python3 "$SKILL_SCRIPTS/url_inspection.py" \
113 --site "$GSC_PROPERTY" \
114 --urls "$PAGE_PATH"
115```
116 
117This gives: indexing status, mobile usability, rich result status, last crawl time.
118 
119### 1f. Load business context (Bash)
120```bash
121BC_FILE="$HOME/.toprank/business-context/$DOMAIN.json"
122[ -f "$BC_FILE" ] && cat "$BC_FILE" || echo "NOT_FOUND"
123```
124 
125If not found, infer what you can from the page content. Don't run the full
126business context interview — this is a page-level skill, not a site onboarding.
127 
128---
129 
130## Phase 2 — Page Content Extraction
131 
132From the fetched HTML, extract:
133 
1341. **Metadata**: `<title>`, `<meta name="description">`, `<meta name="robots">`,
135 canonical URL, OG tags (`og:title`, `og:description`, `og:image`),
136 Twitter Card tags
1372. **Headings**: full heading hierarchy (H1, H2, H3, H4)
1383. **Content body**: main content text (strip nav, footer, sidebar)
1394. **Word count**: total words in main content
1405. **Internal links**: all internal links with anchor text
1416. **External links**: all outbound links with anchor text and domains
1427. **Images**: all images with alt text, src, dimensions if available
1438. **Schema markup**: all `<script type="application/ld+json">` blocks
1449. **Technical signals**: viewport meta, render-blocking resources, lazy loading,
145 HTTPS status, font loading
14610. **Publish/update date**: look for `<time>`, `datePublished`, `dateModified`,
147 or visible dates on the page
148 
149---
150 
151## Phase 3 — Content Quality Evaluation
152 
153Read `references/content-quality-framework.md` for the full scoring rubric.
154 
155### Indexability Gate (check FIRST)
156 
157Before scoring anything, check if the page is indexable:
158- Is there a `<meta name="robots" content="noindex">` tag?
159- Is robots.txt blocking the URL?
160- Does URL Inspection show `NOT_INDEXED` or `CRAWLED_CURRENTLY_NOT_INDEXED`?
161- Is the canonical pointing to a different URL?
162 
163If the page is NOT indexable, **stop scoring and lead the report with this.** No
164amount of content quality matters if Google can't or won't index the page. Report
165the indexability blocker as the #1 Priority Fix with a "Critical" severity, then
166continue with the content evaluation noting that scores are academic until
167indexability is fixed.
168 
169### Content Quality Evaluation
170 
171Evaluate the page across all six dimensions. For each dimension, assign a score
1720-10 with specific evidence from the page content. The framework file has detailed
173criteria for each score level — follow them precisely.
174 
175### 3a. Search Intent Alignment (weight: 20%)
176 
177Determine what search queries this page should rank for:
178- **From GSC** (if available): use actual ranking queries from Phase 1c
179- **From content**: infer the primary target keyword from the title, H1, and
180 content focus
181- **From URL**: the slug often reveals the target keyword
182 
183**Critical: avoid circular reasoning.** Do NOT infer the correct intent from the
184page's own content — that would mean a mismatched page always appears "aligned."
185Instead, use the SERP reality check from Phase 1a-2: look at what actually ranks
186for the primary keyword. If the top 5 results are all comparison listicles and this
187page is a product page, that's a mismatch — regardless of what the page says about
188itself. The SERP is the ground truth for intent, not the page.
189 
190Classify the intent (informational, commercial, transactional, navigational) based
191on the SERP results and the keyword signals, then evaluate whether this page's
192format matches. A blog post for transactional intent is a mismatch. A thin product
193page for informational intent is a mismatch.
194 
195Also check SERP feature alignment — is the content structured to win featured
196snippets, People Also Ask, or other relevant SERP features visible in the actual
197SERP for this keyword?
198 
199### 3b. E-E-A-T Evaluation (weight: 20%)
200 
201Score each of the four E-E-A-T axes independently using the rubric in the
202framework reference:
203 
204- **Experience**: first-hand experience signals, specific examples, original data
205- **Expertise**: depth of knowledge, edge cases, technical accuracy
206- **Authoritativeness**: author credentials, site topical authority, internal linking
207- **Trustworthiness**: source citations, transparency, accuracy, HTTPS
208 
209Check for YMYL status — if the page covers health, finance, legal, or safety
210topics, apply the higher E-E-A-T bar and note this in the report.
211 
212### 3c. Content Quality & Depth (weight: 20%)
213 
214Evaluate:
215- **Comprehensiveness**: does the page fully answer the query vs top competitors?
216- **Original value**: what does this page offer that others don't?
217- **The "Last Click" test**: after reading, would the searcher need to search again?
218- **Helpful Content signals**: positive signals present, negative signals absent
219- **Word count appropriateness**: not thin (for the topic), not padded
220- **Freshness**: content currency, dated references, broken links
221 
222### 3d. On-Page SEO (weight: 15%)
223 
224Evaluate each on-page factor from the framework:
225- Title tag (length, keyword, intent match, uniqueness, CTR appeal)
226- Meta description (length, keyword, CTA, uniqueness)
227- Headings (H1 presence, hierarchy, keywords, descriptiveness)
228- Internal linking (count, anchor text quality, relevance)
229- External linking (citations, source quality)
230- Image optimization (alt text, format, sizing, lazy loading)
231- URL structure (readable, keyword-rich, depth)
232 
233### 3e. Content Structure & UX (weight: 15%)
234 
235Evaluate:
236- Readability (paragraph length, sentence variety, vocabulary level)
237- Content UX (above-fold value, visual breaks, TOC, mobile-friendliness)
238- Scanning ability (bold phrases, bullets, numbered lists)
239 
240### 3f. Technical SEO (weight: 10%)
241 
242Evaluate:
243- Indexability (robots.txt, noindex, canonical, URL Inspection status)
244- Core Web Vitals proxies (render-blocking resources, image weight, DOM complexity)
245- Mobile readiness (viewport, responsive design, touch targets)
246- Schema markup (appropriate type, required fields, no errors)
247- Security (HTTPS, no mixed content)
248 
249---
250 
251## Phase 4 — GSC Performance Context
252 
253**Skip this phase if GSC data was unavailable.**
254 
255Analyze the page's actual search performance:
256 
257### Ranking Queries
258For each query this page ranks for (from GSC):
259- Current position, clicks, impressions, CTR
260- Expected CTR for that position (use standard CTR curves)
261- Gap: is CTR above or below expected?
262- Intent classification of the query
263 
264### CTR Benchmarks
265Use these position-based CTR benchmarks for the Gap column. Do NOT make up your own
266numbers — use this table or write "N/A" if the position is outside range:
267 
268| Position | Expected CTR (informational) | Expected CTR (transactional) | Expected CTR (branded) |
269|----------|------------------------------|------------------------------|------------------------|
270| 1 | 25-30% | 20-25% | 40-50% |
271| 2 | 13-17% | 12-15% | 15-20% |
272| 3 | 9-12% | 8-11% | 8-12% |
273| 4-5 | 5-8% | 5-7% | 4-6% |
274| 6-7 | 3-5% | 3-4% | 2-4% |
275| 8-10 | 1.5-3% | 1.5-3% | 1-2% |
276| 11-20 | 0.5-1.5% | 0.5-1% | <1% |
277 
278SERP features (featured snippets, ads, knowledge panels) can suppress organic CTR
279by 30-50%. If the SERP for a query has a featured snippet, apply a ~30% discount
280to the expected CTR when calculating the gap.
281 
282### CTR Analysis
283If CTR is below expected for the position:
284- Is it a title tag problem? (title doesn't match query intent)
285- Is it a meta description problem? (no compelling reason to click)
286- Is it a SERP feature issue? (featured snippet, ads, or rich results pushing organic down)
287 
288### Trend
289Is traffic to this page growing, stable, or declining? If declining:
290- When did the decline start?
291- Correlate with algorithm updates, content changes, or competitive entries
292 
293### Cannibalization Check
294Are other pages on the same site competing for the same queries? If so:
295- Which page is winning?
296- Should this page be consolidated, differentiated, or canonicalized?
297 
298---
299 
300## Phase 5 — Competitive Quick-Check
301 
302You already have SERP data from the Phase 1a-2 WebSearch. Now **WebFetch the top
3032-3 competitor URLs** from those results to get their actual content. Do not try to
304estimate word count or content depth from search snippets — snippets are ~160
305characters and tell you nothing about page depth. You need the real HTML.
306 
307For each fetched competitor page:
308- Count the actual word count in the main content
309- Note the page type and content format (blog, product, guide, listicle, etc.)
310- List the H2 headings to see what subtopics they cover
311- Note any SERP features they hold (featured snippet, FAQ, etc.)
312- Identify what they cover that the analyzed page doesn't (content gaps)
313- Identify what the analyzed page has that they don't (competitive advantages)
314 
315This gives context for the depth and quality scores — "good enough" depends on
316what the competition is doing. A 1,500-word page might be great if competitors
317average 800 words, or woefully thin if they average 3,000.
318 
319---
320 
321## Phase 6 — Report
322 
323Output the report in this exact format:
324 
325---
326 
327# Page SEO Analysis — [page URL]
328*[date] · [GSC data: date range, or "No GSC data"]*
329 
330## Overall Score: [X.X]/10
331 
332| Dimension | Score | Weight | Weighted |
333|-----------|-------|--------|----------|
334| Search Intent Alignment | X/10 | 20% | X.X |
335| E-E-A-T Signals | X/10 | 20% | X.X |
336| Content Quality & Depth | X/10 | 20% | X.X |
337| On-Page SEO | X/10 | 15% | X.X |
338| Content Structure & UX | X/10 | 15% | X.X |
339| Technical SEO | X/10 | 10% | X.X |
340| **Overall** | | | **X.X** |
341 
342---
343 
344## Top Priority Fixes
345 
3463-5 specific, actionable fixes ordered by expected impact. Each fix must reference
347a specific element on the page and explain exactly what to change.
348 
349**#1 — [Short title]**
350🔴 Critical / 🟡 High / 🟢 Medium
351**Score impact**: [which dimension this improves and by how much]
352**Current**: [what exists now — quote the actual element]
353**Fix**: [exact replacement or action — copy-paste ready where possible]
354**Why**: [mechanism — how this fix improves rankings/CTR/quality]
355 
356*(Repeat for each fix)*
357 
358---
359 
360## E-E-A-T Breakdown
361 
362| Signal | Score | Evidence |
363|--------|-------|----------|
364| Experience | X/10 | [specific evidence from the page] |
365| Expertise | X/10 | [specific evidence] |
366| Authoritativeness | X/10 | [specific evidence] |
367| Trustworthiness | X/10 | [specific evidence] |
368 
369[YMYL flag if applicable]
370 
371### E-E-A-T Gaps to Close
372- [Specific gap #1 with fix]
373- [Specific gap #2 with fix]
374 
375---
376 
377## Search Intent Analysis
378 
379**Target keyword**: [inferred or from GSC]
380**Intent type**: [informational / commercial / transactional / navigational]
381**Content format match**: [Yes / Partial / Mismatch — with explanation]
382 
383### SERP Feature Opportunities
384| Feature | Optimized? | Fix |
385|---------|-----------|-----|
386| Featured Snippet | Yes/No | [what to add/change] |
387| People Also Ask | Yes/No | [FAQ section needed?] |
388| Rich Results | Yes/No | [schema needed?] |
389 
390---
391 
392## On-Page SEO Audit
393 
394### Metadata
395| Element | Current | Status | Recommendation |
396|---------|---------|--------|----------------|
397| Title tag | "[actual title]" ([N] chars) | OK / Too long / Missing keyword | [fix] |
398| Meta description | "[actual]" ([N] chars) | OK / Missing / Too short | [fix] |
399| H1 | "[actual]" | OK / Missing / Duplicate | [fix] |
400| Canonical | [URL] | OK / Missing / Wrong | [fix] |
401| OG tags | Present / Missing | OK / Incomplete | [fix] |
402 
403### Heading Structure
404```
405H1: [actual]
406 H2: [actual]
407 H3: [actual]
408 H2: [actual]
409 ...
410```
411[Assessment: logical hierarchy? Keywords in headings? Descriptive?]
412 
413### Internal Links
414Found [N] internal links. [Assessment of quality, anchor text, relevance]
415 
416| Anchor Text | Target | Quality |
417|-------------|--------|---------|
418| [text] | [URL] | Good / Generic / Missing |
419 
420### Images
421Found [N] images.
422| Image | Alt Text | Format | Issues |
423|-------|----------|--------|--------|
424| [src] | [alt or "MISSING"] | [format] | [lazy loading, sizing, etc.] |
425 
426---
427 
428## Content Quality Assessment
429 
430### Helpful Content Signals
431| Signal | Present? | Evidence |
432|--------|----------|----------|
433| Clear target audience | Yes/No | [evidence] |
434| Answers query completely | Yes/No | [evidence] |
435| Original value added | Yes/No | [evidence] |
436| Passes "Last Click" test | Yes/No | [evidence] |
437| Appropriate depth | Yes/No | [word count: N] |
438| First-hand knowledge | Yes/No | [evidence] |
439 
440### Content Gaps vs Competitors
441| Topic/Subtopic | This Page | Competitors | Action |
442|----------------|-----------|-------------|--------|
443| [subtopic] | Missing / Covered | Covered by [N] of [M] | Add section |
444 
445---
446 
447## Technical SEO
448 
449| Check | Status | Details |
450|-------|--------|---------|
451| Indexability | Indexed / Not Indexed / Blocked | [details from URL Inspection or robots.txt] |
452| Mobile Ready | Yes / Issues | [viewport, responsive, touch targets] |
453| Schema Markup | [types found] / None | [appropriate? errors?] |
454| Page Speed Signals | [render-blocking count, image weight] | [recommendations] |
455| HTTPS | Yes / No | |
456 
457---
458 
459## GSC Performance Summary
460*(Skip if no GSC data)*
461 
462| Metric | Value |
463|--------|-------|
464| Clicks (90d) | X |
465| Impressions (90d) | X |
466| Avg CTR | X% |
467| Avg Position | X |
468| Trend | Growing / Stable / Declining |
469 
470### Top Ranking Queries
471| Query | Position | Clicks | Impressions | CTR | Expected CTR | Gap |
472|-------|----------|--------|-------------|-----|-------------|-----|
473| [query] | X | X | X | X% | X% | +/-X% |
474 
475---
476 
477## What to Improve Next
478 
479After fixing the Top Priority items, these are the next-tier improvements:
480 
4811. [Lower-priority improvement #1]
4822. [Lower-priority improvement #2]
4833. [Lower-priority improvement #3]
484 
485---
486 
487## Skill Handoffs
488 
489Based on findings, offer relevant next steps:
490 
491- If metadata issues found: "Run `/meta-tags-optimizer [page URL]` for optimized
492 title and meta description variants with A/B test suggestions."
493- If schema gaps found: "Run `/schema-markup-generator [page URL]` for correct
494 JSON-LD markup."
495- If content needs rewriting: "Run `/content-writer` with the target keyword and
496 this analysis as context."
497- If deeper keyword analysis needed: "Run `/keyword-research` to find additional
498 keywords this page could target."
499- If full site audit needed: "Run `/seo-analysis` for a complete site-wide audit
500 including all pages."
501 
502---
503 
504## Report Rules
505 
5061. **Every score needs evidence.** Don't assign a 7/10 without citing what earned
507 the 7 and what prevented an 8. Quote actual content from the page.
5082. **Fixes must be specific.** "Improve the title tag" is useless. "Change the
509 title from 'Services' to 'Emergency Roof Repair in Portland — Same-Day
510 Appointments | Example Roofing' (68 chars)" is actionable.
5113. **Use GSC data to ground recommendations.** If you know the page ranks #7 for
512 "roof repair portland" with 1,200 impressions and 2.1% CTR, say that — and
513 estimate the click gain from moving to #3.
5144. **Compare to competitors.** A "good" page can still be below the bar if every
515 competitor is better. Context matters.
5165. **Flag the single biggest unlock.** If one change would have outsized impact
517 (e.g., the page targets the wrong intent entirely), lead with that even if
518 other issues are more numerous.
519 

Discussion

Alternatives

Also in SEO & keywordsSee all 364 in Marketing →