Files
Cassel 647cbec54f docs: update all documentation and add AI tooling configs
- Rewrite README.md with current architecture, features and stack
- Update docs/API.md with all current endpoints (corporate, BI, client 360)
- Update docs/ARCHITECTURE.md with cache, modular queries, services, ETL
- Update docs/GUIA-USUARIO.md for all roles (admin, corporate, agente)
- Add docs/INDEX.md documentation index
- Add PROJETO.md comprehensive project reference
- Add BI-CCC-Implementation-Guide.md
- Include AI agent configs (.claude, .agents, .gemini, _bmad)
- Add netbird VPN configuration
- Add status report

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 13:29:03 -04:00

15 KiB

SEO Validation Guide

For: WDS Agents performing Agentic Development Purpose: Verify SEO implementation against specification before presenting to user When: After a public page is built and previewable (browser or deployed)


Core Principle

Every public page must pass SEO validation before approval.

The agent verifies all measurable SEO criteria using browser tools (Puppeteer, MCP browser-tools, or manual inspection). SEO failures caught during development cost minutes to fix. SEO failures caught after deployment cost rankings and traffic.


When to Run SEO Validation

Trigger Action
Public page section complete (4c/4d) Run SEO checks before presenting
Full page implementation complete Run complete SEO audit
Pre-deployment review Full validation against spec + project brief
Post-deployment verification Validate live URL matches specification

Reference Documents

Before running validation, gather:

  1. Page specification — SEO & Search section (keywords, URL, headings, meta)
  2. Project brief — SEO Strategy section (page-keyword map, structured data plan)
  3. SEO Strategy Guide../../data/agent-guides/saga/seo-strategy-guide.md

SEO Validation Checklist

Level 1: Critical (Must Pass)

These are the top errors found in real-world SEO audits. Failing any of these blocks approval.

1.1 Page Title Tag

Verify:
- Title tag exists and is not empty
- Length ≤ 60 characters (check each language)
- Contains primary keyword
- Contains brand name
- Is unique (different from other pages)
- Matches specification

Report:
"Page title is 'Bilservice på Öland | Källa Fordonservice' (51 chars)
— contains keyword 'bilservice', includes brand. ✓ Passes"

"Page title is 'Home' (4 chars)
— too short, no keyword, no brand. ✗ Fails"

1.2 Meta Description

Verify:
- Meta description tag exists and is not empty
- Length 150-160 characters
- Contains primary keyword
- Contains call-to-action
- Matches specification

Report:
"Meta description is 156 chars, contains 'bilservice Öland', ends with
'Ring oss idag!' ✓ Passes"

"Meta description is missing. ✗ Fails — 80% of audited sites miss this"

1.3 H1 Heading

Verify:
- Exactly ONE <h1> tag on the page
- Contains primary keyword (natural, not stuffed)
- Is visible (not hidden)
- Matches specification

Report:
"Found 1 <h1>: 'Bilservice och reparationer på Öland'
— contains keyword 'bilservice'. ✓ Passes"

"Found 0 <h1> tags. ✗ Fails — 75% of audited sites have H1 issues"

"Found 3 <h1> tags. ✗ Fails — only one H1 allowed per page"

1.4 Heading Hierarchy

Verify:
- Headings follow logical order (H1 → H2 → H3)
- No skipped levels (H1 → H3 without H2)
- No duplicate H1

Report:
"Heading hierarchy: H1 → H2 → H3 → H2 → H3 ✓ Logical flow"

"Heading hierarchy: H1 → H3 (skipped H2) ✗ Fix: Change H3 to H2"

1.5 Image Alt Text

Verify:
- ALL images have alt attributes
- Alt text is descriptive (not empty, not "image")
- Alt text exists in all required languages
- Decorative images have alt="" (empty, not missing)

Report:
"Found 8 images:
  hero-image: alt='Källa Fordonservice verkstad...' ✓
  service-ac: alt='AC-service på personbil' ✓
  icon-phone: alt='' (decorative) ✓
  team-photo: alt attribute MISSING ✗

Result: 7/8 images pass. 1 missing alt text."

Level 2: Important (Should Pass)

2.1 Open Graph / Social Sharing

Verify:
- og:title tag present
- og:description tag present
- og:image tag present (valid URL, image exists)
- og:type tag present
- twitter:card tag present

Report:
"Social sharing tags:
  og:title: 'Bilservice Öland — Källa Fordonservice' ✓
  og:description: present (148 chars) ✓
  og:image: '/images/social/hem-social.jpg' ✓ (file exists)
  og:type: 'website' ✓
  twitter:card: 'summary_large_image' ✓
All social tags present."

"Missing: og:image ✗ — 70% of audited sites miss social tags"

2.2 Structured Data (Schema.org)

Verify:
- JSON-LD script tag exists
- Schema type matches project brief plan
- Required properties present (name, address, phone for LocalBusiness)
- JSON is valid (parseable)

Report:
"Structured data found:
  @type: 'AutoRepair' ✓
  name: 'Källa Fordonservice' ✓
  address: complete ✓
  telephone: '+46485-27070' ✓
  openingHours: present ✓
JSON-LD validates. ✓ Passes"

"No structured data found. ✗ Fails — spec requires LocalBusiness schema"
Verify:
- Page has at least 2 internal links to other pages
- Links have descriptive anchor text (not "click here", "read more")
- No broken internal links (404s)
- No redirect chains (link → 301 → 301 → page)

Report:
"Internal links found: 5
  'Läs mer om AC-service' → /ac-service ✓ Descriptive
  'Ring oss' → tel:+46485-27070 ✓ CTA
  'Klicka här' → /kontakt ✗ Non-descriptive anchor text

Result: 4/5 links pass."

2.4 URL / Slug

Verify:
- URL slug matches specification
- Slug is lowercase
- Uses hyphens (not underscores or spaces)
- No special characters (ä, ö, å)
- Keyword present in slug

Report:
"URL slug: /ac-service ✓ Matches spec, lowercase, keyword present"

"URL slug: /Sida?id=42 ✗ Not descriptive, no keyword"

2.5 Canonical URL

Verify:
- <link rel="canonical"> tag present
- Points to the correct URL (self-referencing)
- One canonical per page

Report:
"Canonical: <link rel='canonical' href='https://kallafordon.se/ac-service'> ✓"

"Canonical tag missing. ✗ Fails"

Level 3: Technical (Verify on Deployment)

These checks apply to the deployed/preview site, not the prototype.

3.1 Performance

Verify:
- Total page weight < 3MB
- Largest image < 400KB (hero) / < 200KB (other)
- Time to First Byte (TTFB) < 1.5s
- No uncompressed images (should be WebP or compressed JPEG)

Report:
"Page weight: 1.8MB ✓ (target < 3MB)
  hero.jpg: 380KB ✓ (target < 400KB)
  team.jpg: 1.2MB ✗ (target < 200KB — compress!)
  icon.svg: 3KB ✓
TTFB: 0.8s ✓ (target < 1.5s)"

3.2 robots.txt

Verify:
- robots.txt exists (not 404)
- Allows crawling of public pages
- References sitemap
- Blocks admin/private pages

Report:
"robots.txt: exists ✓
  Sitemap reference: present ✓
  Public pages: allowed ✓
  /wp-admin/: blocked ✓"

3.3 XML Sitemap

Verify:
- Sitemap exists at /sitemap.xml (or referenced location)
- Contains all public pages
- All URLs return 200 (no broken links)
- Includes all language versions (if multilingual)

Report:
"Sitemap: 32 URLs, all return 200 ✓
  Includes /en/ versions ✓
  Includes /de/ versions ✓"

3.4 hreflang Tags (Multilingual)

Verify:
- Each page declares all language alternates
- x-default points to primary language
- Tags are reciprocal (EN page links to SE, SE page links to EN)

Report:
"hreflang tags on /ac-service:
  sv: /ac-service ✓
  en: /en/ac-service ✓
  de: /de/ac-service ✓
  x-default: /ac-service ✓
All reciprocal. ✓ Passes"

3.5 Security Headers

Verify:
- HSTS present
- X-Content-Type-Options present
- X-Frame-Options present
- Referrer-Policy present

Report:
"Security headers: 2/6 present ✗
  HSTS: missing
  CSP: missing
  X-Content-Type-Options: 'nosniff' ✓
  X-Frame-Options: 'DENY' ✓
  Referrer-Policy: missing
  Permissions-Policy: missing

Note: 95% of audited sites fail security headers."

3.6 Favicon

Verify:
- Favicon exists (check <link rel="icon">)
- Multiple sizes available (16x16, 32x32, 180x180)

Report:
"Favicon: present ✓
  16x16: ✓
  32x32: ✓
  apple-touch-icon (180x180): ✓"

Verification with Puppeteer

Automated SEO Check Script Pattern

// Navigate to page
await page.goto(pageUrl, { waitUntil: 'networkidle0' });

// 1. Title tag
const title = await page.title();
console.log(`Title: "${title}" (${title.length} chars)`);

// 2. Meta description
const metaDesc = await page.$eval(
  'meta[name="description"]',
  el => el.content
).catch(() => null);
console.log(`Meta desc: "${metaDesc}" (${metaDesc?.length || 0} chars)`);

// 3. H1 count and content
const h1s = await page.$$eval('h1', els => els.map(el => el.textContent.trim()));
console.log(`H1 tags: ${h1s.length} — "${h1s.join('", "')}"`);

// 4. Heading hierarchy
const headings = await page.$$eval('h1,h2,h3,h4,h5,h6', els =>
  els.map(el => ({ tag: el.tagName, text: el.textContent.trim().substring(0, 50) }))
);
console.log('Heading hierarchy:', headings.map(h => h.tag).join(' → '));

// 5. Images without alt
const imagesNoAlt = await page.$$eval('img', els =>
  els.filter(el => !el.hasAttribute('alt')).map(el => el.src)
);
console.log(`Images without alt: ${imagesNoAlt.length}`);

// 6. Open Graph tags
const ogTags = await page.$$eval('meta[property^="og:"]', els =>
  els.map(el => ({ property: el.getAttribute('property'), content: el.content }))
);
console.log(`OG tags: ${ogTags.length}`, ogTags);

// 7. Structured data
const jsonLd = await page.$$eval('script[type="application/ld+json"]', els =>
  els.map(el => JSON.parse(el.textContent))
).catch(() => []);
console.log(`Structured data: ${jsonLd.length} blocks`, jsonLd.map(j => j['@type']));

// 8. Canonical
const canonical = await page.$eval('link[rel="canonical"]', el => el.href).catch(() => null);
console.log(`Canonical: ${canonical || 'MISSING'}`);

// 9. Internal links
const links = await page.$$eval('a[href]', els =>
  els.filter(el => el.href.startsWith(window.location.origin))
    .map(el => ({ text: el.textContent.trim().substring(0, 40), href: el.href }))
);
console.log(`Internal links: ${links.length}`);

Narration Pattern

Group results by severity and narrate clearly:

## SEO Validation Report: {Page Name}

### Critical ✓/✗
  Title tag: "Bilservice Öland | Källa Fordonservice" (51 chars) ✓
  Meta description: "Komplett bilverkstad..." (156 chars) ✓
  H1: 1 found — "Bilservice och reparationer på Öland" ✓
  Heading hierarchy: H1 → H2 → H3 → H2 → H3 ✓
  Image alt text: 7/8 images have alt ✗ (team-photo missing)

### Important ✓/✗
  Open Graph: 5/5 tags present ✓
  Structured data: AutoRepair schema valid ✓
  Internal links: 5 found, 4/5 descriptive ✗ (1 "Klicka här")
  URL slug: /ac-service ✓
  Canonical: present, self-referencing ✓

### Technical (deployment only)
  Page weight: 1.8MB ✓
  Image sizes: 1 oversized (team.jpg 1.2MB) ✗
  Security headers: 2/6 ✗

### Summary
  Critical: 4/5 pass
  Important: 4/5 pass
  Technical: 1/3 pass

  Action needed: Fix 1 missing alt text, 1 non-descriptive link,
  1 oversized image, 4 security headers.

Integration with Phase 5 Flow

4a: Announce & Gather
4b: Create Story File
4c: Implement Section
        ↓
   Agent runs Puppeteer verification (INLINE-TESTING-GUIDE)
   Agent runs SEO validation (THIS GUIDE) — for public pages only
        ↓
  All pass? ── No ──→ Agent fixes, re-verifies (loop)
        │
       Yes
        ↓
4d: Present for Testing

Story File Addition

Add SEO criteria to the story file's Agent-Verifiable section:

### SEO Criteria (Public Pages)

| # | Criterion | Expected | How to Verify |
|---|-----------|----------|---------------|
| S1 | Title tag | "Bilservice Öland \| Källa" ≤60 chars | Read document.title |
| S2 | Meta description | 150-160 chars, keyword present | Read meta[name=description] |
| S3 | H1 count | Exactly 1 | Count h1 elements |
| S4 | H1 keyword | Contains "bilservice" | Read h1 textContent |
| S5 | Heading hierarchy | H1→H2→H3, no skips | Scan all headings |
| S6 | Image alt coverage | 100% images have alt | Check img elements |
| S7 | OG tags | og:title, og:description, og:image | Check meta[property^=og:] |
| S8 | Internal links | ≥ 2, descriptive text | Count and check a[href] |

Integration with Acceptance Testing

When creating test scenarios (Phase 4 [H] Handover / Phase 5 [T] Acceptance Testing), include SEO as a test category:

seo_checks:
  - id: 'SEO-001'
    name: 'Page title correct'
    verify:
      - 'Title tag matches specification'
      - 'Title ≤ 60 characters'
      - 'Contains primary keyword'

  - id: 'SEO-002'
    name: 'Meta description correct'
    verify:
      - 'Meta description matches specification'
      - 'Length 150-160 characters'
      - 'Contains CTA'

  - id: 'SEO-003'
    name: 'Heading structure valid'
    verify:
      - 'Exactly one H1'
      - 'No skipped heading levels'

  - id: 'SEO-004'
    name: 'Image alt text complete'
    verify:
      - 'All content images have alt text'
      - 'Alt text in correct language'

  - id: 'SEO-005'
    name: 'Structured data valid'
    verify:
      - 'JSON-LD present and parseable'
      - 'Schema type matches plan'
      - 'Required properties present'

Anti-Patterns

  • Never skip SEO validation on public pages — It's not optional
  • Never approve a page with missing alt text — 85% of real sites fail this
  • Never use "click here" or "read more" as link text — Describe the destination
  • Never have more than one H1 — One per page, always
  • Never deploy without meta description — 80% of sites miss this
  • Never assume SEO "can be added later" — It's specification, not decoration

Common Fixes (From 44 Real-World Audits)

Issue Frequency Fix Time Fix
Missing alt text 85% 1 min/image Add descriptive alt attribute
Missing meta description 80% 2 min/page Add meta tag from spec
H1 missing or wrong 75% 1 min Add/fix h1 tag
Missing OG tags 70% 3 min/page Add og: meta tags from spec
Missing structured data 65% 5 min/page Add JSON-LD script
Oversized images 65% 2 min/image Compress + convert to WebP
Non-descriptive links 30% 1 min/link Rewrite anchor text
Missing canonical 40% 1 min Add link rel=canonical

Total estimated fix time for a typical page: 15-20 minutes These are all preventable by validating during development.


  • Inline Testing Guide: INLINE-TESTING-GUIDE.md — General Puppeteer verification
  • SEO Strategy Guide: ../../data/agent-guides/saga/seo-strategy-guide.md — SEO reference
  • SEO Content Instructions: ../../4-ux-design/templates/instructions/seo-content.instructions.md — Spec-level SEO
  • Specification Quality: ../../data/agent-guides/freya/specification-quality.md — Quality checklist
  • Meta Content Guide: ../../data/agent-guides/freya/meta-content-guide.md — Meta tag details

SEO validation during development = zero SEO issues at launch. Validate as you build.