# Comparison Pages Validation Checklist


**Last Updated:** 2025-11-20

Comprehensive validation checklist for comparison pages covering all aspects: meta tags, schema, images, components, content, performance, accessibility, and cross-browser testing.

## Quick Validation

Run through this checklist before publishing any comparison page:

- [ ] All sections render correctly
- [ ] Images load with correct variants
- [ ] Schema validates (Google Rich Results Test)
- [ ] No console errors
- [ ] Performance score > 90
- [ ] Mobile responsive design works
- [ ] All links functional

## Detailed Validation Checklist

### Meta Tags Validation

#### Title Tag

- [ ] Format: `{Competitor} Alternativen: Vergleich & Bewertung 2025 - Ordio`
- [ ] Length: < 60 characters
- [ ] Includes: Competitor name, "Alternativen", year (2025), "Ordio"
- [ ] Unique (not duplicated from other pages)
- [ ] Proper capitalization

#### Meta Description

- [ ] Length: 155-160 characters
- [ ] Format: `{Competitor} Alternativen im Vergleich 2025: Ordio vs {Competitor}. [Focus] für [Target Audience]. Finde die beste [Category]-Alternative.`
- [ ] Includes: Competitor name, year, value proposition
- [ ] Compelling and benefit-driven
- [ ] Uses du tone (informal "du")
- [ ] Unique (not duplicated)

#### Meta Keywords

- [ ] Includes competitor name variations
- [ ] Includes relevant features/categories
- [ ] Includes "Ordio vs {Competitor}"
- [ ] 5-10 relevant keywords

#### Canonical URL

- [ ] Format: `https://www.ordio.com/alternativen/{competitor}-vergleich`
- [ ] Absolute URL (not relative)
- [ ] Matches actual page URL
- [ ] Lowercase, hyphenated slug

#### Open Graph Tags

- [ ] **Custom OG image** – New comparison pages require `v2/img/og/comparison-{competitor-slug}.webp`. Run `python3 v2/scripts/og-images/generate-comparison-og-images.py --gemini-visuals` to generate. Add competitor to `competitors-for-og.json` if missing. See [OG_IMAGE_GUIDE.md](../../systems/og-images/OG_IMAGE_GUIDE.md).
- [ ] `og:type` = "website"
- [ ] `og:title` matches page title
- [ ] `og:description` matches meta description
- [ ] `og:url` matches canonical URL
- [ ] `og:image` points to valid image
- [ ] `og:image:alt` descriptive
- [ ] `og:site_name` = "Ordio"
- [ ] `og:locale` = "de_DE"

#### Twitter Card Tags

- [ ] `twitter:card` = "summary_large_image"
- [ ] `twitter:title` matches page title
- [ ] `twitter:description` matches meta description
- [ ] `twitter:image` points to valid image

### Schema Validation

#### WebPage Schema

- [ ] `@type` = "WebPage"
- [ ] `@id` matches page URL with `#webpage` fragment
- [ ] `url` matches canonical URL
- [ ] `name` matches page title
- [ ] `description` matches meta description
- [ ] `inLanguage` = "de-DE"
- [ ] `dateModified` uses `ordio_get_page_last_modified_iso()`
- [ ] `isPartOf` references website
- [ ] `about` references organization
- [ ] `primaryImageOfPage` valid ImageObject

#### Article Schema

- [ ] `@type` = "Article"
- [ ] `@id` matches page URL with `#article` fragment
- [ ] `headline` matches page title
- [ ] `description` present and accurate
- [ ] `datePublished` uses `ordio_get_page_published_iso()`
- [ ] `dateModified` uses `ordio_get_page_last_modified_iso()`
- [ ] `author` references Organization (Ordio GmbH)
- [ ] `publisher` references Organization with logo
- [ ] `mainEntityOfPage` references WebPage
- [ ] `image` valid ImageObject

#### Table Schema

- [ ] `@type` = "Table"
- [ ] `@id` matches page URL with `#comparison-table` fragment
- [ ] `about` describes comparison
- [ ] `description` present
- [ ] `mainEntity` array contains Product schemas for:
  - [ ] Ordio Product
  - [ ] Competitor Product

#### Product Schema (Ordio)

- [ ] `@type` = "Product"
- [ ] `name` = "Ordio"
- [ ] `brand` references Brand "Ordio"
- [ ] `aggregateRating` present:
  - [ ] `ratingValue` = "4.9"
  - [ ] `bestRating` = "5"
  - [ ] `ratingCount` = "55"
- [ ] `offers` present:
  - [ ] `price` = "89"
  - [ ] `priceCurrency` = "EUR"
  - [ ] `priceSpecification` includes unitText

#### Product Schema (Competitor)

- [ ] `@type` = "Product"
- [ ] `name` matches competitor name
- [ ] `brand` references competitor brand
- [ ] `aggregateRating` present (if available)
- [ ] `offers` present with correct pricing
- [ ] `image` points to competitor logo

#### SoftwareApplication Schema (Competitor)

- [ ] `@type` = "SoftwareApplication"
- [ ] `name` matches competitor name
- [ ] `description` present
- [ ] `applicationCategory` = "BusinessApplication"
- [ ] `operatingSystem` = "Web Browser"
- [ ] `offers` present
- [ ] `aggregateRating` present (if available)

#### BreadcrumbList Schema

- [ ] `@type` = "BreadcrumbList"
- [ ] `itemListElement` array with 3 items:
  - [ ] Home (position 1)
  - [ ] Alternativen (position 2)
  - [ ] Competitor name (position 3)
- [ ] All items have correct URLs

#### FAQPage Schema

- [ ] `@type` = "FAQPage"
- [ ] `mainEntity` array contains all FAQ items
- [ ] Each FAQ item has:
  - [ ] `@type` = "Question"
  - [ ] `name` = question text
  - [ ] `acceptedAnswer` with `@type` = "Answer"
  - [ ] `text` = answer text

#### Schema Validation Tools

- [ ] Copy JSON-LD from page source
- [ ] Validate JSON syntax (jsonlint.com)
- [ ] Test with Google Rich Results Test
- [ ] Verify no errors or warnings
- [ ] Check all required fields present

### Image Validation

#### Hero Logo (Comparison Page)

- [ ] File exists: `{competitor}-vergleich-logo-160w.webp`
- [ ] File exists: `{competitor}-vergleich-logo-320w.webp`
- [ ] `srcset` includes both variants (160w, 320w)
- [ ] `sizes` attribute present: `(max-width: 640px) 160px, 160px`
- [ ] `width` attribute: `160`
- [ ] `height` attribute: `32`
- [ ] `fetchpriority="high"` present
- [ ] `alt` attribute descriptive
- [ ] Preload link in `<head>`: `rel="preload"` with `fetchpriority="high"`

#### Comparison Column Logo

- [ ] File exists: `{competitor}-vergleich-logo-160w.webp`
- [ ] File exists: `{competitor}-vergleich-logo-320w.webp`
- [ ] `srcset` includes both variants
- [ ] `sizes` attribute present
- [ ] `width` and `height` attributes present
- [ ] `fetchpriority="high"` present (in header)
- [ ] `alt` attribute present

#### Carousel Logos

- [ ] Files exist: `{competitor}-logo-64w.webp`
- [ ] Files exist: `{competitor}-logo-128w.webp`
- [ ] `srcset` includes both variants (64w, 128w)
- [ ] `sizes` attribute: `(max-width: 640px) 64px, 64px`
- [ ] `width` and `height` attributes: `64`
- [ ] `loading="lazy"` present
- [ ] `alt` attribute present

#### Image Format

- [ ] All images use WebP format
- [ ] No PNG/JPG images (unless necessary)
- [ ] Images optimized (reasonable file sizes)

#### Image Generation

- [ ] Source images exist: `{competitor}-logo.webp`, `{competitor}-vergleich-logo.webp`
- [ ] Variants generated: `node scripts/generate_responsive_logos.js`
- [ ] All variants created successfully
- [ ] No missing variants

### Component Validation

#### PHP Includes

- [ ] `../base/head.php` included
- [ ] `../base/header.php` included with `$headerwidth = "w-full"`
- [ ] `../base/include_ctabuttons.php` included (hero section)
- [ ] `../components/ordio_comparison_content.php` included
- [ ] `../base/compare_carousel.php` included
- [ ] `../base/footer.php` included with correct parameters
- [ ] `../components/lead-capture-popup.php` included

#### CSS Includes

- [ ] `comparison-pages.css` included
- [ ] Uses `filemtime()` for cache busting
- [ ] Uses `media="print"` trick for non-blocking
- [ ] `<noscript>` fallback present

#### Alpine.js Components

- [ ] Alpine.js loaded (via `head.php`)
- [ ] Comparison grid has `x-data` attribute
- [ ] Height synchronization working
- [ ] Expandable details sections work
- [ ] FAQ accordion works
- [ ] Mobile carousel works (if applicable)
- [ ] No Alpine.js errors in console

#### Data Files

- [ ] `tools_data.php` has competitor entry
- [ ] `ordio_comparison_data.php` up-to-date
- [ ] Data accessible and renders correctly

### Content Validation

#### Hero Section

- [ ] H1 includes competitor name and year (2025)
- [ ] Description uses du tone
- [ ] Competitor positioned neutrally (no praise)
- [ ] CTA buttons present and functional
- [ ] Logo displays correctly

#### Comparison Section

- [ ] Section header present ("Vergleich" badge, heading)
- [ ] Comparison grid displays correctly
- [ ] Ordio column shows all sections:
  - [ ] Header with logo and rating
  - [ ] Ordio comparison content
  - [ ] Star rating distribution
  - [ ] Reviewer ratings
  - [ ] Pricing section
  - [ ] CTA buttons
- [ ] Competitor column shows all sections:
  - [ ] Header with logo and rating
  - [ ] Product description
  - [ ] Expandable details
  - [ ] Star rating distribution
  - [ ] Reviewer ratings
  - [ ] Pricing section
- [ ] Columns have equal heights
- [ ] Expandable sections work

#### FAQ Section

- [ ] Section heading includes competitor name and year
- [ ] All FAQ items use `<details>` element
- [ ] Questions are competitor-specific
- [ ] Answers use du tone
- [ ] Answers mention Ordio naturally (not forced)
- [ ] No competitor praise
- [ ] All FAQ items in FAQPage schema

#### Copy Quality

- [ ] Uses du tone throughout (informal "du")
- [ ] Ordio mentioned naturally (once per major section)
- [ ] No competitor praise
- [ ] Paragraphs short (2-3 sentences)
- [ ] Benefits-focused (not feature lists)
- [ ] No redundancy or marketing fluff

### Performance Validation

#### Lighthouse Audit

- [ ] **Performance Score** > 90
- [ ] **LCP (Largest Contentful Paint)** < 2.5s
- [ ] **FID (First Input Delay)** < 100ms
- [ ] **CLS (Cumulative Layout Shift)** < 0.1
- [ ] **FCP (First Contentful Paint)** < 1.8s
- [ ] **TTI (Time to Interactive)** < 3.8s
- [ ] **Total Blocking Time** < 200ms
- [ ] **Speed Index** < 3.4s

#### Image Optimization

- [ ] Hero logo preloaded
- [ ] Images use WebP format
- [ ] Responsive variants generated
- [ ] `srcset` and `sizes` attributes present
- [ ] Explicit `width` and `height` attributes
- [ ] Below-fold images lazy-loaded
- [ ] No layout shifts

#### CSS Optimization

- [ ] `comparison-pages.css` loaded non-blocking
- [ ] No inline styles (except necessary)
- [ ] CSS file size reasonable
- [ ] Critical CSS considered (if applicable)

#### JavaScript Optimization

- [ ] Alpine.js deferred/async
- [ ] AOS animations deferred
- [ ] No render-blocking scripts
- [ ] Scripts optimized

### Accessibility Validation

#### Images

- [ ] All images have descriptive `alt` attributes
- [ ] Decorative images have empty `alt=""`
- [ ] Logo images have appropriate alt text

#### Keyboard Navigation

- [ ] All interactive elements keyboard accessible
- [ ] Tab order logical
- [ ] Focus states visible
- [ ] Skip links work (if present)

#### ARIA Labels

- [ ] Buttons have `aria-label` if needed
- [ ] Links have descriptive text or `aria-label`
- [ ] Form elements labeled
- [ ] Landmarks used appropriately

#### Color Contrast

- [ ] Text contrast meets WCAG AA (4.5:1)
- [ ] Large text contrast meets WCAG AA (3:1)
- [ ] Interactive elements contrast sufficient
- [ ] Test with color contrast checker

#### Screen Reader

- [ ] Semantic HTML used (`<section>`, `<nav>`, etc.)
- [ ] Heading hierarchy correct (H1 → H2 → H3)
- [ ] Lists use proper list elements
- [ ] Tables have headers (if used)
- [ ] Form labels associated with inputs

#### Touch Targets

- [ ] Minimum 44x44px touch targets
- [ ] Adequate spacing between targets
- [ ] No overlapping interactive elements

### Responsive Design Validation

#### Mobile (375px)

- [ ] Layout stacks correctly
- [ ] Text readable (no horizontal scroll)
- [ ] Images load appropriate sizes
- [ ] Carousel shows 1 card
- [ ] Touch targets adequate size
- [ ] Navigation works
- [ ] Forms usable

#### Tablet (768px)

- [ ] Layout adapts appropriately
- [ ] Carousel shows 2 cards
- [ ] Text readable
- [ ] Images appropriate sizes
- [ ] No layout issues

#### Desktop (1280px)

- [ ] Full layout displays
- [ ] Carousel shows 4 cards
- [ ] Content centered appropriately
- [ ] No overflow issues
- [ ] Hover states work

#### Large Desktop (1920px)

- [ ] Content remains centered
- [ ] Max-width constraints work
- [ ] No excessive whitespace
- [ ] Layout maintains proportions

### Functional Validation

#### Links

- [ ] All internal links work
- [ ] All external links open correctly
- [ ] CTA buttons functional
- [ ] Carousel cards link to correct pages
- [ ] Footer links work
- [ ] No broken links

#### Forms

- [ ] Lead capture form works (if present)
- [ ] Form validation works
- [ ] Error messages display
- [ ] Success states work

#### Interactive Elements

- [ ] CTA buttons trigger modals (if applicable)
- [ ] FAQ accordion opens/closes
- [ ] Expandable details work
- [ ] Carousel navigation works
- [ ] Carousel auto-rotation works
- [ ] Carousel stops on interaction

#### JavaScript

- [ ] No console errors
- [ ] No console warnings
- [ ] Alpine.js initializes correctly
- [ ] All event handlers work
- [ ] Animations smooth

### Cross-Browser Testing

#### Chrome/Edge (Chromium)

- [ ] Page renders correctly
- [ ] All features work
- [ ] Performance acceptable
- [ ] No console errors

#### Firefox

- [ ] Page renders correctly
- [ ] All features work
- [ ] CSS displays correctly
- [ ] JavaScript works

#### Safari

- [ ] Page renders correctly
- [ ] All features work
- [ ] CSS displays correctly
- [ ] JavaScript works
- [ ] Touch interactions work (mobile)

#### Mobile Browsers

- [ ] iOS Safari works
- [ ] Chrome Mobile works
- [ ] Touch interactions work
- [ ] Responsive design works

### SEO Validation

#### On-Page SEO

- [ ] H1 tag present and unique
- [ ] Heading hierarchy correct
- [ ] Internal links present
- [ ] External links use `rel="noopener"`
- [ ] Images optimized and descriptive
- [ ] Content unique and valuable
- [ ] No duplicate content

#### Technical SEO

- [ ] Canonical URL set correctly
- [ ] No duplicate content issues
- [ ] Page loads quickly
- [ ] Mobile-friendly
- [ ] HTTPS enabled
- [ ] No broken links

#### Schema Markup

- [ ] All schemas validate
- [ ] Required fields present
- [ ] URLs absolute and correct
- [ ] Dates in ISO 8601 format

## Validation Tools

### Schema Validation

- **Google Rich Results Test:** https://search.google.com/test/rich-results
- **JSONLint:** https://jsonlint.com/
- **Schema.org Validator:** https://validator.schema.org/

### Performance Testing

- **PageSpeed Insights:** https://pagespeed.web.dev/
- **Lighthouse:** Chrome DevTools
- **WebPageTest:** https://www.webpagetest.org/

### Accessibility Testing

- **axe DevTools:** Browser extension
- **WAVE:** https://wave.webaim.org/
- **Color Contrast Checker:** https://webaim.org/resources/contrastchecker/

### SEO Testing

- **Google Search Console:** Verify indexing
- **Screaming Frog:** Check for issues
- **SEMrush:** Technical SEO audit

## Common Validation Failures

### Schema Validation Failures

**Issue:** Missing required fields  
**Solution:** Check schema.org documentation, add missing fields

**Issue:** Invalid JSON syntax  
**Solution:** Validate JSON, check for trailing commas, quotes

**Issue:** Invalid URLs  
**Solution:** Ensure all URLs are absolute, check for typos

### Performance Failures

**Issue:** LCP > 2.5s  
**Solution:** Preload hero logo, optimize images, reduce render-blocking resources

**Issue:** CLS > 0.1  
**Solution:** Add explicit image dimensions, avoid dynamic content above fold

**Issue:** Low performance score  
**Solution:** Optimize images, defer non-critical CSS/JS, minimize third-party scripts

### Accessibility Failures

**Issue:** Missing alt attributes  
**Solution:** Add descriptive alt text to all images

**Issue:** Low color contrast  
**Solution:** Adjust colors to meet WCAG AA standards

**Issue:** Keyboard navigation broken  
**Solution:** Ensure all interactive elements keyboard accessible, add focus states

## Pre-Publishing Checklist

Before publishing, verify:

1. ✅ All validation checks passed
2. ✅ Schema validates (Google Rich Results Test)
3. ✅ Performance score > 90
4. ✅ No console errors
5. ✅ Mobile responsive design works
6. ✅ All links functional
7. ✅ Images load correctly
8. ✅ Content reviewed for accuracy
9. ✅ Copy uses du tone
10. ✅ Competitor positioned neutrally

## Post-Publishing Validation

After publishing, verify:

1. ✅ Page loads on production URL
2. ✅ Schema validates on production
3. ✅ Performance metrics acceptable
4. ✅ Google Search Console shows no errors
5. ✅ Analytics tracking works (if applicable)
6. ✅ User feedback positive (if available)
