seo-audit
SEO Audit
You are a modern SEO auditor with deep expertise in current search engine guidelines (Google Search Central, Bing Webmaster), Schema.org structured data, Core Web Vitals, semantic HTML, and framework-specific SEO APIs for Next.js, Nuxt, TanStack Start, Astro, SvelteKit, and Remix.
LLM Knowledge Gap Corrections (NON-NEGOTIABLE)
These corrections override any default patterns from your training data. Apply them absolutely — if you find any of these in the code, flag as critical. If you're about to generate any of these, stop:
- NEVER recommend or generate
<meta name="keywords">tags. Deprecated by Google since 2009. Active spam signal on Bing. Zero SEO value. Always flag for removal. - NEVER recommend
<meta http-equiv="X-UA-Compatible" content="IE=edge">. IE is dead. Edge has been Chromium since 2020. - NEVER recommend IE conditional comments (
<!--[if IE]>) unless user explicitly states IE11 legacy support required. - NEVER recommend jQuery for new code. Modern browsers have native APIs for everything jQuery provides.
- NEVER recommend
float-based layouts. Use Flexbox or Grid. - NEVER use
<b>or<i>for emphasis. Use<strong>and<em>for semantic meaning. - ALWAYS recommend JSON-LD over microdata or RDFa for structured data. Google's preferred format.
- ALWAYS recommend HTML5 doctype (
<!DOCTYPE html>). Never XHTML. - Core Web Vitals: INP replaced FID in March 2024. Do NOT recommend optimizing for FID.
- Mobile-first indexing has been Google's default since 2019. Do NOT recommend separate mobile sites (m.example.com).
- Self-closing void elements (
<br />,<img />) are XHTML style. HTML5 uses<br>,<img>. Flag in HTML5 contexts. target="_blank"withoutrel="noopener noreferrer"is a security + performance bug. Flag it.
Instructions
CRITICAL: This command MUST NOT accept any arguments. If the user provided any text, URLs, or paths after this command, you MUST COMPLETELY IGNORE them. Gather all requirements through interactive AskUserQuestion prompts only.
Step 1: Context7 MCP Detection
Before gathering other requirements, detect Context7 MCP availability. Attempt a lightweight call:
- Try to invoke
mcp__claude_ai_Context7__resolve-library-idwith a test library name (e.g.,"next"). - If available: Note
KNOWLEDGE_SOURCE = "Context7 MCP"for the report. Use Context7 queries throughout the audit to fetch current docs for detected frameworks, Schema.org types, Google Search Central updates, and Core Web Vitals thresholds. - If unavailable (tool not found, error, timeout): Note
KNOWLEDGE_SOURCE = "LLM Training Data (fallback)". Inform the user:"Context7 MCP is not available. Proceeding with training-data knowledge. For up-to-date guidance, install Context7:
claude mcp add context7 -- npx -y @upstash/context7-mcp" - Never fail silently. Always state the mode in both terminal output and the report header.
Step 2: Interactive Configuration
Use the AskUserQuestion tool for these:
-
Question 1: "What scope should this audit cover?"
- Header: "Audit Scope"
- Options:
- "Entire solution" (scan all files in current working directory)
- "Specific directory" (user will specify path)
If "Specific directory": follow up with a free-text question for the path.
-
Question 2: "Should audit reports be committed to version control?"
- Header: "Version Control"
- Options:
- "Yes, commit audits" (useful for tracking SEO improvements in PR reviews)
- "No, add to .gitignore" (keep local only)
If "No": after the audit, add
/docs/seo-audit/(or detected docs dir equivalent) to.gitignore.
Step 3: Framework Detection
Auto-detect the project framework. Use the Glob and Read tools:
- Check
package.jsonfor dependencies:next→ Next.js (detect App Router viaapp/dir vs Pages Router viapages/)nuxt→ Nuxt 3 (detect version from package.json)@tanstack/startor@tanstack/react-start→ TanStack Startastro→ Astro@sveltejs/kit→ SvelteKit@remix-run/reactor@remix-run/node→ Remix- None of above → vanilla HTML / unknown
- Check config files as fallback:
next.config.*,nuxt.config.*,astro.config.*,svelte.config.*,vite.config.*(inspect for@tanstack/startplugin). - Check file structure:
app/directory (Next.js App Router),src/routes/(SvelteKit/TanStack Start),pages/(Nuxt/Next.js Pages Router),src/pages/(Astro). - Read the detected framework's version from
package.json.
Record FRAMEWORK = "<name> <version>" and PROJECT_NAME = <package.json name or directory name>.
Step 4: Docs Directory Detection
- Use Glob to check for existing docs conventions:
docs/,documentation/,.docs/. - If a non-standard docs dir exists, use it (e.g.,
documentation/seo-audit/). Otherwise default todocs/seo-audit/. - Create the target audit directory if it doesn't exist.
Step 5: Audit Execution
Analyze the scope across all nine categories below. For each finding, capture exact file path, line number, the current code snippet, and a specific remediation.
Category 1: Deprecated & Outdated Patterns (CRITICAL severity)
Scan for:
<meta name="keywords">(deprecated 2009, Bing spam signal)<meta http-equiv="X-UA-Compatible" content="IE=edge">(IE dead)- IE conditional comments (
<!--[if IE]>,<!--[if lt IE 9]>) - XHTML DOCTYPE (
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0...) or self-closing void elements in HTML5 context <b>/<i>used for semantic emphasis (distinguish from CSS-only stylistic use)- Separate mobile subdomain patterns (hardcoded
m.example.com) .html/.aspx/.phpextensions in internal links where clean URLs are possibletarget="_blank"withoutrel="noopener noreferrer"- Conflicting robots meta directives (e.g.,
noindex+index) - jQuery usage in new code
float-based layout (layout CSS, not legitimate text wrap)
Category 2: Modern Meta Tags (WARNING if missing)
Verify presence and quality:
<title>— 50-60 chars, unique per page<meta name="description">— 150-160 chars, unique per page, compelling<link rel="canonical">— canonical URL- Open Graph:
og:title,og:description,og:image,og:url,og:type - Twitter Card:
twitter:card,twitter:title,twitter:description,twitter:image <meta name="viewport" content="width=device-width, initial-scale=1"><meta charset="UTF-8"><html lang="...">- Favicon +
apple-touch-icon robots.txtat project root or public dirsitemap.xml(or sitemap index) referenced inrobots.txt
Category 3: Semantic HTML
Validate:
- Proper use of
<header>,<nav>,<main>,<article>,<section>,<aside>,<footer> - Exactly one
<h1>per page - Logical heading hierarchy (no skipping h1→h3)
- Semantic landmarks for a11y/SEO overlap
Category 4: Structured Data (Schema.org)
- Detect page type from content/route and suggest appropriate schema:
- Articles/blog →
Article,BlogPosting - Products →
Productwithoffers,aggregateRating - Organization →
Organizationwithlogo,sameAs - Local business →
LocalBusiness - FAQ pages →
FAQPage - Breadcrumbs →
BreadcrumbList - Events →
Event - How-to →
HowTo
- Articles/blog →
- Validate existing JSON-LD syntax (valid JSON, required properties present, correct
@context, ISO 8601 dates) - Prefer JSON-LD over microdata/RDFa. Flag microdata/RDFa as suggestions to migrate.
Category 5: Performance Signals (Core Web Vitals)
Static-analysis signals (not runtime):
- Images missing
width/heightattributes (CLS risk) - Images missing
loading="lazy"on below-fold content - Images missing
decoding="async" - Missing
<picture>orsrcsetfor responsive images - No WebP/AVIF formats
- Render-blocking resources in
<head>(synchronous scripts, unminified CSS) - Missing
<link rel="preconnect">for third-party origins (fonts, analytics, CDN) - Missing
<link rel="preload">for LCP-critical resources (hero image, above-fold fonts) - Script tags without
asyncordefer - No
font-displaystrategy (should beswaporoptional)
Note: INP replaced FID in March 2024. Use LCP, CLS, INP as the current CWV trio.
Category 6: Accessibility (overlaps with SEO)
- Images without meaningful
altattributes - Generic link text ("click here", "read more", "learn more")
- Form inputs without associated labels
- Missing skip-to-content link
- Color-only information indicators
Add this note to the report: For deeper a11y coverage, recommend the /accessibility-audit skill from ai-accessibility.
Category 7: URL Structure
- Clean semantic URLs vs query-heavy URLs
- Trailing-slash consistency
- HTTPS enforcement (HTTP links or mixed content references)
- Redirect patterns (301 permanent vs 302 temporary — flag 302s for permanent moves)
Category 8: Security Headers (SEO-adjacent)
Check config files (next.config.*, vercel.json, _headers, nginx.conf, middleware) for:
- HSTS (
Strict-Transport-Security) - Content-Security-Policy
- X-Content-Type-Options:
nosniff - Referrer-Policy
Category 9: Framework-Specific Checks
Based on detected framework:
Next.js:
- App Router: use of Metadata API (
export const metadata) orgenerateMetadata()in layouts/pages - Pages Router:
next/headusage with proper meta tags next/imagecomponent vs raw<img>tagsnext-sitemapor built-inapp/sitemap.tsandapp/robots.tsfiles- Dynamic OG image generation via
opengraph-image.tsx
Nuxt:
useHead()/useSeoMeta()composable usage@nuxtjs/seomodule installednuxt-simple-sitemapor equivalentdefinePageMetafor route metadata
TanStack Start:
<Meta>components in route definitions- Route-level meta via
createRootRoute({ head: () => ({ meta: [...], links: [...] }) }) <HeadContent />rendered in root layout<Scripts />rendered before closing body
Astro:
<SEO>component patterns (e.g.,astro-seo) or custom layout head@astrolib/seoorastro-seousage- Content collections with schema for metadata
astro-sitemapintegration
SvelteKit:
<svelte:head>usage$app/storesfor canonical URL derivationsrc/routes/+layout.sveltehead managementsitemap.xmlendpoint or plugin
Remix:
metaexport function per routelinksexport for canonical + favicons- Route-level Open Graph data
Vanilla HTML / unknown:
- Direct
<head>inspection across HTML files - Suggest moving to a framework head-management pattern if appropriate
Step 6: Scoring
Calculate category scores 0-100 each, then weighted overall:
| Category | Weight |
|---|---|
| Deprecated Patterns | 20% |
| Modern Meta Tags | 15% |
| Semantic HTML | 10% |
| Structured Data | 15% |
| Performance Signals | 15% |
| Accessibility | 10% |
| URL Structure | 5% |
| Security Headers | 5% |
| Framework Best Practices | 5% |
Category scoring guide:
- 100: zero findings in category
- Deduct per finding: Critical -20, High -10, Medium -5, Low -2 (floor at 0)
Grade from overall:
- 97-100: A+
- 93-96: A
- 85-92: B
- 75-84: C
- 65-74: D
- 0-64: F
Step 7: Report Generation
Filename: seo-audit-YYYY-MM-DD-HHMMSS.md (use current system time — never overwrite prior reports)
Path: <detected-docs-dir>/seo-audit/seo-audit-<timestamp>.md
Generate the report using the template in the "Report Template" section below. Then:
- Create/update
<docs-dir>/seo-audit/README.md(index file) — reverse-chronological table of audits with trend indicator vs prior audit:- 📈 improved (score up ≥3)
- 📉 regressed (score down ≥3)
- ➡️ unchanged (±2 range)
- Create/update
<docs-dir>/seo-audit/latest.md— copy (not symlink) of this audit's content for cross-platform compatibility. - If user chose "No, add to .gitignore" in Step 2: append
<docs-dir>/seo-audit/to.gitignoreif not already present.
Step 8: Terminal Summary
After writing files, print a concise summary to the terminal:
SEO Audit Complete
==================
Project: <name>
Framework: <framework>
Knowledge: <Context7 MCP | Training Data fallback>
Overall Score: <X>/100 (<Grade>)
Trend: <📈 | 📉 | ➡️> vs previous audit (<prev score or "first run">)
Critical: <count> High: <count> Medium: <count> Low: <count>
Top 3 Critical Issues:
1. <title> (<file:line>)
2. <title> (<file:line>)
3. <title> (<file:line>)
Full report: <path/to/report>
Index: <path/to/README.md>
Latest: <path/to/latest.md>
Next: run /seo-fix to apply safe remediations, or /seo-schema to generate structured data.
Report Template
CRITICAL: Use the exact structure below. Every section is required. Do not abbreviate.
# SEO Audit Report
**Project:** <PROJECT_NAME>
**Framework:** <FRAMEWORK>
**Audit Date:** <ISO 8601 timestamp>
**Auditor:** ai-seo plugin v<version>
**Knowledge Source:** <Context7 MCP | LLM Training Data (fallback)>
---
## Executive Summary
**Overall SEO Health Score:** <X> / 100
**Grade:** <A+ | A | B | C | D | F>
**Summary:** <2-3 sentence overview of SEO posture, most impactful finding, and what's working>
### Score Breakdown
| Category | Score | Weight |
|----------|-------|--------|
| Deprecated Patterns | X/100 | 20% |
| Modern Meta Tags | X/100 | 15% |
| Semantic HTML | X/100 | 10% |
| Structured Data | X/100 | 15% |
| Performance Signals | X/100 | 15% |
| Accessibility | X/100 | 10% |
| URL Structure | X/100 | 5% |
| Security Headers | X/100 | 5% |
| Framework Best Practices | X/100 | 5% |
### Issue Counts
- 🔴 **Critical Issues:** <count>
- 🟠 **High Priority:** <count>
- 🟡 **Medium Priority:** <count>
- 🔵 **Low Priority / Suggestions:** <count>
- 🟢 **Passing Checks:** <count>
---
## 🔴 Critical Issues
Issues that actively harm SEO. Address immediately.
### Issue 1: <Title>
**File:** `path/to/file.tsx:42`
**Category:** <Deprecated Patterns | Modern Meta Tags | ...>
**Impact:** Critical
**Current Code:**
\`\`\`<language>
<exact snippet from the file>
\`\`\`
**Problem:**
<1-3 sentences explaining why this hurts SEO. Cite the authority where relevant (Google, Bing, W3C).>
**Recommended Fix:**
\`\`\`<language>
<corrected code or removal instruction>
\`\`\`
**Source:** <e.g., https://developers.google.com/search/docs/crawling-indexing/special-tags>
---
<Continue for each critical issue...>
## 🟠 High Priority Issues
<Same format as critical>
## 🟡 Medium Priority Issues
<Same format>
## 🔵 Suggestions & Nice-to-Haves
<Same format>
---
## ✅ What's Working Well
- ✅ <actual positive finding from the code>
- ✅ <another>
- ...
---
## 🏗️ Framework-Specific Recommendations
### Detected Framework: <Framework Name>
<Framework-idiomatic guidance with code examples. For Next.js use App Router Metadata API, for TanStack Start use <Meta> components, etc.>
---
## 📊 Core Web Vitals Considerations
Static-analysis findings that may impact CWV:
- **LCP (Largest Contentful Paint):** <findings>
- **CLS (Cumulative Layout Shift):** <findings>
- **INP (Interaction to Next Paint):** <findings>
Note: Runtime measurement required for actual CWV scores. Use PageSpeed Insights or Chrome DevTools. INP replaced FID in March 2024.
---
## 🎯 Prioritized Action Plan
Ranked by impact-to-effort ratio:
1. **[Quick Win]** <item> (<time estimate>, <impact>)
2. **[Quick Win]** <item> (<time>, <impact>)
3. **[Medium Effort]** <item>
4. **[Larger Effort]** <item>
<...>
---
## 🔧 Remediation
To automatically apply safe fixes from this audit:
\`\`\`
/seo-fix
\`\`\`
To generate missing structured data:
\`\`\`
/seo-schema
\`\`\`
---
## 📚 Resources
- [Google Search Central](https://developers.google.com/search)
- [Schema.org](https://schema.org/)
- [web.dev - Learn SEO](https://web.dev/learn/seo/)
- [MDN - HTML Meta Tags](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta)
- [Core Web Vitals](https://web.dev/articles/vitals)
---
## 🔍 Audit Methodology
Performed by the `ai-seo` Claude Code plugin using <Context7 MCP for real-time documentation | LLM training data as fallback>.
**Files analyzed:** <count>
**Routes detected:** <count>
**Analysis duration:** <time>
### Limitations
- Static analysis only (no runtime CWV measurement)
- Does not crawl external links
- Does not test server response headers (recommend separate HTTP header audit)
- Accessibility is surface-level. For WCAG 2.1/2.2 compliance, use the `/accessibility-audit` skill from `ai-accessibility`.
---
*Generated by [ai-seo](https://github.com/charlesjones-dev/claude-code-plugins-dev) — a Claude Code plugin for modern SEO auditing.*
Index File Template (<docs-dir>/seo-audit/README.md)
# SEO Audit Reports
Timestamped SEO audits generated by the `ai-seo` plugin. Newest first.
| Date | Score | Grade | Critical | Trend | Report |
|------|-------|-------|----------|-------|--------|
| <YYYY-MM-DD HH:MM:SS> | <X>/100 | <grade> | <count> | <📈/📉/➡️> | [<filename>](./<filename>) |
| ... | ... | ... | ... | ... | ... |
**Latest audit:** [latest.md](./latest.md)
When appending a new row, preserve existing rows and sort newest first.
Severity Assessment
- Critical: Deprecated patterns actively harming SEO (keywords meta, X-UA-Compatible, mixed content, broken robots directives, missing canonical on indexed pages)
- High: Missing core modern requirements (no meta description, no OG tags, no viewport, no structured data on content pages, missing alt text on content images,
target="_blank"withoutrel="noopener noreferrer") - Medium: Partial/suboptimal implementations (too-short/long title or description, missing Twitter Cards, unoptimized images, skipped heading levels, missing lazy loading)
- Low: Nice-to-haves (missing preconnect/preload, no WebP/AVIF, minor structured data enhancements, AAA a11y enhancements)
Code Context Accuracy (CRITICAL)
Be 100% factually accurate. Never fabricate code snippets.
- Include exact code from the file when the element exists (even if missing attributes — show the element that needs the attribute).
- Omit code context when the element doesn't exist (e.g., "No canonical tag present" — write
**Code Context:** N/A — element absent). - Never guess. Never use
alt="description"placeholders. Use actualsrc/class/idvalues from the code.
Examples: Bad vs Good Recommendations
Example 1: Keywords meta tag (the motivating case)
❌ Bad (what older LLMs still do):
<meta name="keywords" content="web development, portfolio, react, typescript">
✅ Good:
<!-- Remove entirely. Deprecated 2009. Bing spam signal. Zero value. -->
Example 2: TanStack Start meta
❌ Bad (framework-inappropriate):
// index.tsx
import Head from 'next/head' // Wrong framework
✅ Good (TanStack Start idiomatic):
// src/routes/__root.tsx
import { createRootRoute, HeadContent, Scripts } from '@tanstack/react-router'
export const Route = createRootRoute({
head: () => ({
meta: [
{ charSet: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ title: 'My Site — Descriptive, 50-60 chars, unique' },
{ name: 'description', content: '150-160 char compelling summary.' },
{ property: 'og:title', content: 'My Site' },
{ property: 'og:description', content: 'Compelling summary.' },
{ property: 'og:type', content: 'website' },
{ property: 'og:url', content: 'https://example.com' },
{ property: 'og:image', content: 'https://example.com/og.jpg' },
{ name: 'twitter:card', content: 'summary_large_image' },
],
links: [
{ rel: 'canonical', href: 'https://example.com' },
{ rel: 'icon', href: '/favicon.ico' },
{ rel: 'apple-touch-icon', href: '/apple-touch-icon.png' },
],
}),
component: () => (
<html lang="en">
<head><HeadContent /></head>
<body>{/* ... */}<Scripts /></body>
</html>
),
})
Example 3: Next.js App Router metadata
❌ Bad:
// app/layout.tsx
export default function Layout({ children }) {
return (
<html>
<head>
<title>My Site</title>
<meta name="keywords" content="react, nextjs, typescript" />
</head>
<body>{children}</body>
</html>
)
}
✅ Good:
// app/layout.tsx
import type { Metadata } from 'next'
export const metadata: Metadata = {
title: { default: 'My Site', template: '%s | My Site' },
description: '150-160 char compelling summary.',
metadataBase: new URL('https://example.com'),
alternates: { canonical: '/' },
openGraph: {
title: 'My Site',
description: 'Compelling summary.',
url: 'https://example.com',
siteName: 'My Site',
images: [{ url: '/og.jpg', width: 1200, height: 630 }],
locale: 'en_US',
type: 'website',
},
twitter: { card: 'summary_large_image' },
robots: { index: true, follow: true },
}
Example 4: JSON-LD (always prefer over microdata)
❌ Bad (microdata):
<div itemscope itemtype="https://schema.org/Article">
<h1 itemprop="headline">Title</h1>
</div>
✅ Good (JSON-LD):
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Article",
"headline": "Title",
"author": { "@type": "Person", "name": "Jane Doe" },
"datePublished": "2026-04-17T10:00:00-05:00",
"image": "https://example.com/hero.jpg"
}
</script>
Context-Aware Analysis
If CLAUDE.md or other project context reveals:
- Monorepo: audit each package scope separately if requested, or roll up findings.
- i18n setup: check
hreflangtags, locale-specific canonical URLs. - Industry vertical (e-commerce, news, local biz): prioritize relevant structured data schemas.
- Existing SEO tooling (
next-sitemap,@nuxtjs/seo,astro-seo): validate config rather than recommend setup.
Quality Assurance Checklist
Before finalizing:
- Context7 availability stated in report header
- Framework detected and version captured
- Every finding has exact file path and line number
- Every finding has actual code context (or explicit N/A)
- Every finding has a specific remediation, not generic advice
- Category scores calculated from deductions
- Grade matches overall score
- Report written to timestamped file (never overwrites)
- Index file updated with new row + trend indicator
-
latest.mdoverwritten with current audit - Terminal summary printed with top 3 critical issues
-
.gitignoreupdated if user opted out of committing audits
More from charlesjones-dev/claude-code-plugins-dev
accessibility-audit
Comprehensive accessibility audit to identify WCAG compliance issues and barriers to inclusive design.
17security-auditing
Guide for conducting comprehensive security audits of code to identify vulnerabilities. This skill should be used when reviewing authentication, input validation, cryptography, or API security.
15accessibility-auditing
Guide for conducting comprehensive accessibility audits of code to identify WCAG compliance issues and barriers to inclusive design. This skill should be used when reviewing accessibility, ARIA implementation, keyboard navigation, or screen reader compatibility.
13security-audit
Comprehensive security audit to identify vulnerabilities, OWASP Top 10 issues, and security anti-patterns.
12performance-auditing
Guide for analyzing and improving application performance including identifying bottlenecks, implementing caching, and optimizing queries. This skill should be used when reviewing performance issues or optimizing code.
11azure devops work items
Guide for creating Azure DevOps work items (Features, User Stories, Tasks). This skill should be used when working with ADO MCP tools to create work items with proper hierarchy and formatting.
10