
Seo Fundamentals
Run an automated on-repo SEO audit on public HTML and React page files before you ship or refresh landing and marketing routes.
Overview
seo-fundamentals is an agent skill for the Launch phase that audits HTML and React page files in your repo for meta tags, Open Graph, heading hierarchy, and image alt best practices.
Install
npx skills add https://github.com/davila7/claude-code-templates --skill seo-fundamentalsWhat is this skill?
- Python auditor scans HTML plus JSX/TSX components that look like public pages
- Verifies meta title, description, and Open Graph tags for social sharing
- Validates heading hierarchy and image alt attributes for accessibility and SEO
- Skips node_modules, tests, docs, and utility modules so results focus on shippable URLs
- CLI usage: python seo_checker.py <project_path> with JSON-friendly stdout on Windows UTF-8
- Checks four SEO areas: meta tags, Open Graph, heading hierarchy, and image alt attributes
- Targets HTML files and JSX/TSX page components while skipping tests and utility modules
Adoption & trust: 522 installs on skills.sh; 27.8k GitHub stars; 3/3 security scanners passed (skills.sh audits).
What problem does it solve?
You shipped or refactored pages but have no quick way to see which routes are missing titles, descriptions, OG tags, or proper headings and alt text.
Who is it for?
Indie builders with static sites or Next/React apps who want a lightweight technical SEO sweep without paying for a full crawler suite.
Skip if: Teams that only need blog keyword research, rank tracking, or performance/CWV measurement—the checker does not score content quality or page speed.
When should I use this skill?
You need to verify SEO best practices on HTML/JSX/TSX pages that are likely public-facing before ship or launch refresh.
What do I get? / Deliverables
You get a structured SEO audit report scoped to likely public pages so you can fix markup issues before indexing and social sharing.
- SEO audit findings for eligible page files in the project path
- Actionable gaps on meta, OG, headings, and image alt coverage
Recommended Skills
Journey fit
Canonical shelf is Launch because the checker validates discoverability signals—titles, meta, Open Graph, headings, and image alt—that matter when pages go live or get indexed. Fits the seo subphase as a technical SEO hygiene pass on real page sources, not generic copywriting or keyword research.
How it compares
Use instead of manual view-source spot checks when you need consistent rules across every page component in the tree.
Common Questions / FAQ
Who is seo-fundamentals for?
Solo and indie developers shipping web apps or marketing sites who want agent-guided, repeatable SEO markup checks on real page files.
When should I use seo-fundamentals?
Use it during Launch (seo) before or right after publishing routes, and after large UI refactors when meta and heading structure may have drifted.
Is seo-fundamentals safe to install?
The skill runs a local Python auditor over your filesystem; review the Security Audits panel on this Prism page and inspect the script before running it on sensitive repos.
SKILL.md
READMESKILL.md - Seo Fundamentals
#!/usr/bin/env python3 """ SEO Checker - Search Engine Optimization Audit Checks HTML/JSX/TSX pages for SEO best practices. PURPOSE: - Verify meta tags, titles, descriptions - Check Open Graph tags for social sharing - Validate heading hierarchy - Check image accessibility (alt attributes) WHAT IT CHECKS: - HTML files (actual web pages) - JSX/TSX files (React page components) - Only files that are likely PUBLIC pages Usage: python seo_checker.py <project_path> """ import sys import json import re from pathlib import Path from datetime import datetime # Fix Windows console encoding try: sys.stdout.reconfigure(encoding='utf-8', errors='replace') except: pass # Directories to skip SKIP_DIRS = { 'node_modules', '.next', 'dist', 'build', '.git', '.github', '__pycache__', '.vscode', '.idea', 'coverage', 'test', 'tests', '__tests__', 'spec', 'docs', 'documentation', 'examples' } # Files to skip (not pages) SKIP_PATTERNS = [ 'config', 'setup', 'util', 'helper', 'hook', 'context', 'store', 'service', 'api', 'lib', 'constant', 'type', 'interface', 'mock', '.test.', '.spec.', '_test.', '_spec.' ] def is_page_file(file_path: Path) -> bool: """Check if this file is likely a public-facing page.""" name = file_path.name.lower() stem = file_path.stem.lower() # Skip utility/config files if any(skip in name for skip in SKIP_PATTERNS): return False # Check path - pages in specific directories are likely pages parts = [p.lower() for p in file_path.parts] page_dirs = ['pages', 'app', 'routes', 'views', 'screens'] if any(d in parts for d in page_dirs): return True # Filename indicators for pages page_names = ['page', 'index', 'home', 'about', 'contact', 'blog', 'post', 'article', 'product', 'landing', 'layout'] if any(p in stem for p in page_names): return True # HTML files are usually pages if file_path.suffix.lower() in ['.html', '.htm']: return True return False def find_pages(project_path: Path) -> list: """Find page files to check.""" patterns = ['**/*.html', '**/*.htm', '**/*.jsx', '**/*.tsx'] files = [] for pattern in patterns: for f in project_path.glob(pattern): # Skip excluded directories if any(skip in f.parts for skip in SKIP_DIRS): continue # Check if it's likely a page if is_page_file(f): files.append(f) return files[:50] # Limit to 50 files def check_page(file_path: Path) -> dict: """Check a single page for SEO issues.""" issues = [] try: content = file_path.read_text(encoding='utf-8', errors='ignore') except Exception as e: return {"file": str(file_path.name), "issues": [f"Error: {e}"]} # Detect if this is a layout/template file (has Head component) is_layout = 'Head>' in content or '<head' in content.lower() # 1. Title tag has_title = '<title' in content.lower() or 'title=' in content or 'Head>' in content if not has_title and is_layout: issues.append("Missing <title> tag") # 2. Meta description has_description = 'name="description"' in content.lower() or 'name=\'description\'' in content.lower() if not has_description and is_layout: issues.append("Missing meta description") # 3. Open Graph tags has_og = 'og:' in content or 'property="og:' in content.lower() if not has_og and is_layout: issues.append("Missing Open Graph tags") # 4. Heading hierarchy - multiple H1s h1_matches = re.findall(r'<h1[^>]*>', content, re.I) if len(h1_matches) > 1: issues.append(f"Multiple H1 tags ({len(h1_matches)})") # 5. Images without alt img_pattern = r'<img[^>]+>' imgs = re.findall(img_pattern, content, re.I) for img in imgs: i