---
name: tools-page-seo-optimizer
description: "Framework-agnostic SEO workflow for any site with multiple tool, product, or feature pages. Covers duplicate content, unique meta tags, heading hierarchy, internal linking, URL slugs, E-E-A-T, content registry pattern for scaling 50–500 pages, and blog content strategy for position 50–68 keywords."
category: seo
risk: safe
source: community
source_type: community
author: whoisabhishekadhikari
date_added: "2026-06-19"
tags: [seo, tools-pages, product-pages, duplicate-content, content-registry, meta-tags, internal-linking, url-slugs, e-e-a-t, framework-agnostic]
tools: [claude-code, cursor, codex-cli, gemini-cli, opencode]
version: 1.0.0
---
# Tools Page SEO Optimizer
You are an expert in technical SEO and content strategy for sites with large collections of tool, product, or feature pages. Your workflow is framework-agnostic — applies to Django, Rails, Laravel, Express, Next.js, Nuxt, Astro, WordPress, and static HTML.
Derived from a real audit that found 93 of 105 tool pages sharing identical template prose and ranking at average position 68. This skill is the playbook that fixes it.
---
## Quick-Start Decision Tree
```
Full audit from scratch? → Run all phases in order
All tool pages rank the same? → Phase 2 (Content Registry) first
Meta titles/descriptions all generic? → Phase 1 (Meta Tags)
Tool pages buried / hard to navigate? → Phase 5 (Internal Linking)
Bad URL slugs? → Phase 6 (URL Slug Hygiene)
Site looks authorless to Google? → Phase 7 (E-E-A-T)
Stuck at position 50–68 on keywords? → Phase 9 (Blog Content Strategy)
Fixes deployed but unsure they're live? → Phase 10 (Live Verification)
```
---
## Phase 0 — Codebase Reconnaissance
**Before writing any code**, locate these in the codebase. Names vary by framework — adapt.
| What to find | Common locations |
|---|---|
| URL routing | `routes.rb`, `urls.py`, `routes/`, `pages/`, `app/` |
| Head / meta template | `_head.html`, `layout.js`, `base.html`, `app.blade.php` |
| Tool/page registry | config file, database seed, JSON, `lib/guides.js`, `data/tools.js` |
**Answer these before writing a single line:**
1. How are tool pages generated — static files, database loop, config registry, CMS?
2. Where is the shared template that renders `
`, ``, `
`?
3. Does each tool have its own content fields, or does every tool fall back to the same template prose?
4. Is there a central list of all tool slugs you can iterate over programmatically?
---
## Phase 1 — Meta Titles & Descriptions
### The core problem
Every tool page sharing the same `` template with only the tool name swapped in
is the single most common reason tool sites rank poorly. Google treats near-identical titles
as duplicate pages and demotes all of them.
### Title tag formula
```
{Tool Name} | {Specific Outcome} — {Brand}
```
| ✅ Good | ❌ Bad |
|---|---|
| `Meta Tag Generator \| Create Perfect SEO Titles Free — MySite` | `Meta Tag Generator - MySite Tools` |
| `Broken Link Finder \| Scan Any Page for Dead URLs — MySite` | `Broken Link Finder - Free Online Tool \| MySite` |
**Rules:**
- ≤ 60 characters total
- Primary keyword in the first 40 characters
- Every tool has a **unique** title — no two tools share the same one
- Include "Free" where accurate — measurably improves CTR
### Meta description formula
```
{What it does — one action sentence}. {Key differentiator}. {CTA}.
```
Example: `Scan any webpage for broken links in seconds. Checks internal and external URLs,
exports results as CSV. Free, no account needed.`
**Rules:**
- 120–160 characters
- Action verbs: Generate, Scan, Check, Analyze, Convert, Build, Find
- Every tool gets a **custom** description — zero template filler
### Implementation (any framework)
```html
{{ tool.meta_title | default(tool.name + " | " + site_name) }}
```
### Validation script — run before every deploy
```python
# validate_meta.py
import json, sys
tools = json.load(open('data/tools.json'))
errors = []
for t in tools:
slug = t.get('slug', '?')
title = t.get('meta_title', '')
desc = t.get('meta_description', '')
if not title: errors.append(f"MISSING TITLE: {slug}")
elif len(title) > 60: errors.append(f"TITLE TOO LONG ({len(title)}): {slug}")
if not desc: errors.append(f"MISSING DESC: {slug}")
elif len(desc) < 120: errors.append(f"DESC TOO SHORT ({len(desc)}): {slug}")
elif len(desc) > 160: errors.append(f"DESC TOO LONG ({len(desc)}): {slug}")
if errors:
print('\n'.join(errors)); sys.exit(1)
print(f"✅ All {len(tools)} tools passed meta validation")
```
---
## Phase 2 — Content Registry (The Highest-Leverage Fix)
**Root cause of poor rankings on tool sites:** 80–95% of tool pages share identical
template prose. Google sees them as thin, near-duplicate pages and ranks none well.
Fix this before anything else.
### Diagnosis
```bash
# Find shared prose in your templates — if these strings appear in a shared template
# file, you have the problem
D1=$(grep -rn "powerful tool that helps" templates/ src/ 2>/dev/null | head -5)
[ -n "$D1" ] && echo " ✗ Shared template prose found" || echo " ✓ No shared prose"
D2=$(grep -rn "easy to use" templates/ src/ 2>/dev/null | head -5)
[ -n "$D2" ] && echo " ✗ Template filler found"
```
### Registry entry structure (framework-agnostic)
```yaml
# data/tools/meta-tag-generator.yaml (or JSON, DB columns, JS object — adapt to your stack)
slug: meta-tag-generator
name: Meta Tag Generator
meta_title: "Meta Tag Generator | Create Perfect SEO Titles & Descriptions Free"
meta_description: "Generate optimized title tags and meta descriptions with live character
counters. Enforces Google's 60/160 char limits. Instant, free, no account needed."
introduction: >
The meta tag generator creates the two most critical on-page SEO elements —
your title tag and meta description — with live character counters that enforce
Google's recommended limits before you publish. [80+ unique words minimum]
best_practices:
- "Include your primary keyword within the first 40 characters of the title"
- "Write a unique description per page — duplicate descriptions waste crawl budget"
- "Use action verbs in descriptions: Generate, Find, Check, Analyze"
how_to_steps:
- name: "Enter your page details"
text: "Type your target keyword, page topic, and a brief summary of the content"
- name: "Check the live character counters"
text: "Keep title ≤60 chars and description ≤160 chars"
- name: "Copy and paste the output"
text: "Paste the generated tags into your HTML section"
faqs:
- q: "Does Google always use my meta description?"
a: "No — Google rewrites descriptions ~63% of the time. Write them anyway for
social shares and some SERPs."
- q: "What happens if my title is over 60 characters?"
a: "Google truncates it with an ellipsis, cutting off your message mid-sentence."
related_tools:
- og-tag-generator
- schema-markup-generator
- heading-analyzer
```
### Minimum viable unique content per tool
| Field | Minimum | Priority |
|---|---|---|
| `meta_title` | Unique, ≤60 chars | 🔴 Critical |
| `meta_description` | Unique, 120–160 chars | 🔴 Critical |
| `introduction` | 80+ unique words | 🔴 Critical |
| `best_practices` | 3–5 tool-specific items | 🟡 High |
| `how_to_steps` | 3 real steps for THIS tool | 🟡 High |
| `faqs` | 2 tool-specific Q&As | 🟡 High |
| `related_tools` | 2–4 slug references | 🟢 Medium |
**Rule: complete one tool fully before starting the next.**
---
## Phase 3 — H1 and Heading Hierarchy
### H1 formula
```
{Tool Name} | {Outcome Phrase}
```
**Rules:**
- One `
` per page — only the tool name/title
- Must be unique per page
### Heading hierarchy
```
h1 — Tool name (one per page)
h2 — Major sections: "How It Works", "Best Practices", "FAQs", "Related Tools"
h3 — Subsections: individual FAQ items, feature callouts, step headers
```
Never skip levels. No h1 → h3 without an h2.
```bash
# Audit heading hierarchy on a live page
curl -s "https://yourdomain.com/tools/meta-tag-generator" \
| grep -oE ']*>.*?'
```
---
## Phase 4 — Accessibility
Accessibility failures lower Core Web Vitals scores — a direct ranking signal.
Every icon-only interactive element needs `aria-label`:
```html
```
```bash
# Find icon-only buttons missing aria-label
B=$(grep -rn "