# ============================================================
# SEO (Search Engine Optimization) Rules
# Based on: Google Search Essentials, Schema.org, Core Web Vitals
# ============================================================
metadata:
name: "SEO Standards"
version: "1.0.0"
last_updated: "2026-02-13"
sources:
- name: "Google Search Essentials"
url: "https://developers.google.com/search/docs/essentials"
description: "Google's core guidelines for search visibility"
- name: "Google Search Central - Technical Requirements"
url: "https://developers.google.com/search/docs/crawling-indexing"
- name: "Core Web Vitals"
url: "https://developers.google.com/search/docs/appearance/core-web-vitals"
- name: "Schema.org"
url: "https://schema.org/"
description: "Structured data vocabulary"
- name: "Open Graph Protocol"
url: "https://ogp.me/"
- name: "Lighthouse SEO Audit"
url: "https://developer.chrome.com/docs/lighthouse/seo/"
# ============================================================
# 1. Title & Meta Tags
# ============================================================
rules:
# --- Essential Meta Tags ---
- id: "seo-title-tag"
name: "Title Tag"
description: "Page must have a unique, descriptive
tag"
severity: "critical"
category: "meta"
standard: "Google Search Essentials"
check_type: "meta_tag_check"
details:
tag: "title"
requirements:
- "Must be present and non-empty"
- "Should be 30-60 characters for optimal display"
- "Should be unique across the site"
- "Should accurately describe page content"
max_length: 60
min_length: 10
- id: "seo-meta-description"
name: "Meta Description"
description: "Page should have a descriptive meta description"
severity: "major"
category: "meta"
standard: "Google Search Essentials"
check_type: "meta_tag_check"
details:
tag: ''
requirements:
- "Should be 120-160 characters for optimal display"
- "Should be unique across the site"
- "Should accurately summarize page content"
max_length: 160
min_length: 50
- id: "seo-meta-viewport"
name: "Viewport Meta Tag"
description: "Page must have viewport meta tag for mobile compatibility"
severity: "critical"
category: "meta"
standard: "Google Mobile-First Indexing"
check_type: "meta_tag_check"
details:
tag: ''
recommended_value: "width=device-width, initial-scale=1"
- id: "seo-charset"
name: "Character Encoding"
description: "Page must declare character encoding"
severity: "major"
category: "meta"
standard: "HTML Living Standard"
check_type: "meta_tag_check"
details:
tag: ''
- id: "seo-lang-attribute"
name: "HTML Language Attribute"
description: "HTML element should have lang attribute"
severity: "major"
category: "meta"
standard: "Google Search Essentials"
check_type: "attribute_check"
details:
element: "html"
attribute: "lang"
description: "Helps search engines serve language-appropriate results"
# --- Canonical & Duplicate Content ---
- id: "seo-canonical-url"
name: "Canonical URL"
description: "Page should have a canonical URL to prevent duplicate content"
severity: "major"
category: "meta"
standard: "Google Search Central"
check_type: "link_tag_check"
details:
tag: ''
requirements:
- "Should be an absolute URL"
- "Should point to the preferred version of the page"
- "Must be self-referencing or point to a valid page"
- id: "seo-hreflang"
name: "Hreflang Tags"
description: "Multilingual pages should have hreflang annotations"
severity: "minor"
category: "meta"
standard: "Google Search Central - Internationalization"
check_type: "link_tag_check"
details:
tag: ''
description: "Tells Google which language versions exist for a page"
# --- Robots Control ---
- id: "seo-meta-robots"
name: "Meta Robots Tag"
description: "Check for meta robots directives"
severity: "major"
category: "crawling"
standard: "Google Search Central"
check_type: "meta_tag_check"
details:
tag: ''
valid_values:
- "index"
- "noindex"
- "follow"
- "nofollow"
- "noarchive"
- "nosnippet"
- "max-snippet"
- "max-image-preview"
- "max-video-preview"
warning_values:
- value: "noindex"
message: "Page is blocked from indexing"
- value: "nofollow"
message: "Links on this page will not be followed"
- value: "none"
message: "Page is blocked from indexing and links won't be followed"
# ============================================================
# 2. Content Structure
# ============================================================
- id: "seo-heading-structure"
name: "Heading Structure"
description: "Page should have proper heading hierarchy for SEO"
severity: "major"
category: "content"
standard: "Google Search Essentials"
check_type: "heading_check"
details:
checks:
- id: "has-h1"
description: "Page should have exactly one H1 tag"
severity: "critical"
- id: "h1-not-empty"
description: "H1 tag should not be empty"
severity: "critical"
- id: "heading-hierarchy"
description: "Headings should follow logical hierarchy (no skipping levels)"
severity: "major"
- id: "heading-keywords"
description: "Headings should contain relevant keywords"
severity: "minor"
- id: "no-multiple-h1"
description: "Page should not have multiple H1 tags"
severity: "major"
- id: "seo-image-alt"
name: "Image Alt Text"
description: "Images should have descriptive alt attributes for SEO"
severity: "major"
category: "content"
standard: "Google Search Essentials - Images"
check_type: "image_check"
details:
checks:
- id: "has-alt"
description: "All images should have alt attribute"
severity: "critical"
- id: "alt-not-empty"
description: "Alt text should not be empty (unless decorative)"
severity: "major"
- id: "alt-not-filename"
description: "Alt text should not be just a filename"
severity: "minor"
- id: "alt-not-too-long"
description: "Alt text should be under 125 characters"
max_length: 125
severity: "minor"
- id: "seo-internal-links"
name: "Internal Linking"
description: "Page should have internal links for crawlability"
severity: "minor"
category: "content"
standard: "Google Search Central - Links"
check_type: "link_check"
details:
checks:
- id: "has-internal-links"
description: "Page should contain internal links"
- id: "no-broken-links"
description: "Internal links should not return 404"
- id: "descriptive-anchor"
description: "Link anchor text should be descriptive (not 'click here')"
- id: "seo-content-length"
name: "Content Length"
description: "Page should have sufficient text content"
severity: "minor"
category: "content"
standard: "SEO Best Practice"
check_type: "content_check"
details:
min_word_count: 300
description: "Pages with thin content may rank poorly"
# ============================================================
# 3. Technical SEO
# ============================================================
- id: "seo-robots-txt"
name: "Robots.txt"
description: "Site should have a valid robots.txt file"
severity: "major"
category: "crawling"
standard: "Google Search Central - Robots.txt"
check_type: "file_check"
details:
path: "/robots.txt"
checks:
- id: "exists"
description: "robots.txt file should exist"
- id: "valid-syntax"
description: "robots.txt should have valid syntax"
- id: "not-blocking-important"
description: "Should not block important resources (CSS, JS, images)"
- id: "has-sitemap-reference"
description: "Should reference XML sitemap"
- id: "seo-sitemap-xml"
name: "XML Sitemap"
description: "Site should have a valid XML sitemap"
severity: "major"
category: "crawling"
standard: "Google Search Central - Sitemaps"
check_type: "file_check"
details:
paths:
- "/sitemap.xml"
- "/sitemap_index.xml"
checks:
- id: "exists"
description: "XML sitemap should exist"
- id: "valid-xml"
description: "Sitemap should be valid XML"
- id: "referenced-in-robots"
description: "Sitemap should be referenced in robots.txt"
- id: "seo-https"
name: "HTTPS"
description: "Site should be served over HTTPS"
severity: "critical"
category: "security_seo"
standard: "Google Search Essentials"
check_type: "protocol_check"
details:
description: "HTTPS is a confirmed Google ranking signal"
- id: "seo-mobile-friendly"
name: "Mobile Friendliness"
description: "Page should be mobile-friendly (mobile-first indexing)"
severity: "critical"
category: "mobile"
standard: "Google Mobile-First Indexing"
check_type: "mobile_check"
details:
checks:
- id: "viewport-meta"
description: "Has viewport meta tag"
- id: "responsive-design"
description: "Uses responsive CSS (media queries or fluid layout)"
- id: "no-horizontal-scroll"
description: "No horizontal scrolling at mobile widths"
- id: "readable-font-size"
description: "Font size is readable without zooming (>= 16px base)"
- id: "tap-targets"
description: "Tap targets are at least 48x48 CSS pixels"
- id: "seo-page-speed"
name: "Page Load Speed"
description: "Page should load quickly for better SEO"
severity: "major"
category: "performance_seo"
standard: "Google Core Web Vitals"
check_type: "performance_check"
details:
metrics:
- name: "LCP"
description: "Largest Contentful Paint"
good: "<= 2.5s"
needs_improvement: "<= 4.0s"
poor: "> 4.0s"
- name: "INP"
description: "Interaction to Next Paint"
good: "<= 200ms"
needs_improvement: "<= 500ms"
poor: "> 500ms"
- name: "CLS"
description: "Cumulative Layout Shift"
good: "<= 0.1"
needs_improvement: "<= 0.25"
poor: "> 0.25"
- id: "seo-url-structure"
name: "URL Structure"
description: "URLs should be clean and descriptive"
severity: "minor"
category: "technical"
standard: "Google Search Essentials - URL Structure"
check_type: "url_check"
details:
checks:
- id: "readable-url"
description: "URL should be human-readable (not query strings)"
- id: "no-underscores"
description: "URLs should use hyphens, not underscores"
- id: "lowercase"
description: "URLs should be lowercase"
- id: "no-excessive-depth"
description: "URL path should not be excessively deep (> 4 levels)"
max_depth: 4
- id: "seo-redirect-check"
name: "Redirect Handling"
description: "Check for proper redirect implementation"
severity: "major"
category: "technical"
standard: "Google Search Central - Redirects"
check_type: "redirect_check"
details:
checks:
- id: "no-redirect-chains"
description: "Avoid redirect chains (>2 hops)"
- id: "use-301"
description: "Permanent redirects should use 301 status"
- id: "no-meta-refresh-redirect"
description: "Avoid meta refresh redirects"
# ============================================================
# 4. Structured Data
# ============================================================
- id: "seo-structured-data"
name: "Structured Data (Schema.org)"
description: "Page should include structured data for rich results"
severity: "minor"
category: "structured_data"
standard: "Schema.org / Google Structured Data"
check_type: "structured_data_check"
details:
formats:
- "JSON-LD (recommended)"
- "Microdata"
- "RDFa"
common_types:
- type: "WebSite"
description: "Site-level information with search action"
- type: "Organization"
description: "Organization/company information"
- type: "BreadcrumbList"
description: "Breadcrumb navigation structure"
- type: "Article"
description: "News article, blog post"
- type: "Product"
description: "Product information with reviews/pricing"
- type: "FAQPage"
description: "Frequently asked questions"
- type: "LocalBusiness"
description: "Local business information"
- type: "Event"
description: "Event information"
- type: "Recipe"
description: "Recipe with ingredients and instructions"
- type: "HowTo"
description: "Step-by-step instructions"
- type: "VideoObject"
description: "Video content metadata"
- id: "seo-json-ld-valid"
name: "JSON-LD Validity"
description: "JSON-LD structured data should be valid"
severity: "minor"
category: "structured_data"
standard: "Schema.org"
check_type: "structured_data_check"
details:
checks:
- id: "valid-json"
description: "JSON-LD must be valid JSON"
- id: "has-context"
description: "Must include @context: https://schema.org"
- id: "has-type"
description: "Must include @type property"
- id: "required-properties"
description: "Must include required properties for the type"
# ============================================================
# 5. Social Media / Open Graph
# ============================================================
- id: "seo-open-graph"
name: "Open Graph Tags"
description: "Page should have Open Graph meta tags for social sharing"
severity: "minor"
category: "social"
standard: "Open Graph Protocol"
check_type: "meta_tag_check"
details:
required_tags:
- property: "og:title"
description: "Title for social sharing"
- property: "og:description"
description: "Description for social sharing"
- property: "og:image"
description: "Image for social sharing (min 1200x630px recommended)"
- property: "og:url"
description: "Canonical URL for social sharing"
- property: "og:type"
description: "Content type (website, article, etc.)"
recommended_tags:
- property: "og:site_name"
description: "Website name"
- property: "og:locale"
description: "Locale for the content"
- id: "seo-twitter-cards"
name: "Twitter Card Tags"
description: "Page should have Twitter Card meta tags"
severity: "info"
category: "social"
standard: "Twitter Cards"
check_type: "meta_tag_check"
details:
tags:
- name: "twitter:card"
description: "Card type (summary, summary_large_image, player)"
required: true
- name: "twitter:title"
description: "Title for Twitter sharing"
required: false
- name: "twitter:description"
description: "Description for Twitter sharing"
required: false
- name: "twitter:image"
description: "Image for Twitter sharing"
required: false
# ============================================================
# 6. Crawling & Indexing
# ============================================================
- id: "seo-crawlability"
name: "Page Crawlability"
description: "Page should be crawlable by search engines"
severity: "critical"
category: "crawling"
standard: "Google Search Central"
check_type: "crawl_check"
details:
checks:
- id: "status-200"
description: "Page should return HTTP 200 status"
- id: "not-blocked-robots"
description: "Page should not be blocked by robots.txt"
- id: "not-noindex"
description: "Page should not have noindex directive (unless intended)"
- id: "content-type-html"
description: "Content-Type should be text/html"
- id: "seo-favicon"
name: "Favicon"
description: "Site should have a favicon"
severity: "info"
category: "technical"
standard: "Google Search Central"
check_type: "file_check"
details:
description: "Favicons appear in search results and browser tabs"
check_locations:
- ''
- ''
- "/favicon.ico"
- id: "seo-404-page"
name: "Custom 404 Page"
description: "Site should have a custom 404 error page"
severity: "minor"
category: "technical"
standard: "Google Search Essentials"
check_type: "http_check"
details:
description: "Custom 404 pages help users navigate back to working pages"
- id: "seo-nofollow-usage"
name: "Nofollow Link Usage"
description: "Check for proper use of rel=nofollow on links"
severity: "info"
category: "links"
standard: "Google Search Central - Links"
check_type: "link_check"
details:
rel_values:
- value: "nofollow"
description: "Do not follow this link"
use_case: "User-generated content, untrusted links"
- value: "ugc"
description: "User-generated content"
use_case: "Comments, forum posts"
- value: "sponsored"
description: "Paid/sponsored link"
use_case: "Advertisements, sponsored content"