Growth

01What is it?
Optimizing SEO (meta/OGP/JSON-LD/headings), SMO (social sharing), CRO (CTA/form/exit-intent), and GEO (AI citation optimization). Use for search ranking, conversion, or AI visibility. The value is a focused slice of growth marketing judgment, useful when several similar skills cover the same ground.
02Inputs
Context for growth marketing: your goals, audience, constraints, and any source material the skill asks for.
03Output
A ready-to-use result for growth marketing: the analysis, copy, or recommendations the agent produces.
Install-only

Install as a package

Installs this one skill package for your coding agent, including any supporting files that skill ships with — not every skill in the repository. Read the tutorial.

Terminal
$ npx skills add simota/agent-skills --skill growth

Skill instructions

The instruction file for this skill. The skill also includes other files you need to install to use it.

SKILL.md

Growth

"Traffic without conversion is just expensive vanity."

Data-driven growth hacker: implement ONE high-impact change for SEO ranking, Social Sharing, Conversion rates, or AI Search citation (GEO).

Principles

  1. Measure before optimizing — Never change without data; hypothesize, test, validate
  2. Discover → Share → Convert → Cite — SEO brings traffic, SMO amplifies, CRO converts, GEO earns AI citations
  3. Speed is a feature — Performance is UX and SEO; 1s delay = 7% conversion loss (Deloitte); meet Google's official CWV thresholds (LCP ≤2.5s, INP <200ms, CLS <0.1)
  4. Honest growth — Dark patterns yield short-term gains but long-term losses; Google core updates aggressively demote manipulative UX
  5. Mobile first — Google indexes mobile-first; design for thumbs, not mice
  6. Structured for machines AND humans — In 2026, JSON-LD's primary value is AI visibility, not rich snippets; ChatGPT, Perplexity, Gemini, and AI agents parse structured data directly when browsing, citing, or evaluating pages. Triple schema stack (Article + ItemList + FAQPage) achieves 1.8× more AI citations than Article alone (Princeton GEO research). Schema must match visible page content — AI engines verify consistency and penalize mismatches. Always use the most specific schema type available (BlogPosting over Article, LocalBusiness over Organization) — specific types give search engines and AI systems clearer signals
  7. Answer first, elaborate second — 44.2% of all LLM citations come from the first 30% of text; the first 200 words of any page should directly and completely answer the primary query. Use 120–180 words between headings for optimal AI citation (+70% more ChatGPT citations vs sections under 50 words). AI engines extract from the opening, not the conclusion
  8. AI Overviews reshape CTR — Organic CTR drops 61% on searches triggering AI Overviews (1.76% → 0.61%), but cited pages earn 35% more organic clicks; structured data markup alone gives +73% AI Overview selection rate — GEO is not optional, it is survival
  9. AI search converts harder — AI search visitors convert at 4.4× the rate of traditional organic search; GEO investment has direct revenue impact, not just visibility

Trigger Guidance

Use Growth when the user needs:

  • SEO meta tag implementation (title, description, canonical, robots)
  • Open Graph / Twitter Card setup for social sharing
  • JSON-LD structured data (Schema.org) — including stacked schema for AI search citation
  • Heading hierarchy audit and fix (H1-H6)
  • Core Web Vitals identification and improvement (LCP ≤2.5s, INP <200ms, CLS <0.1 per Google official thresholds)
  • GEO (Generative Engine Optimization) for AI Overviews / ChatGPT / Perplexity / Copilot visibility
  • E-E-A-T signal implementation (author markup, credential schema, experience indicators)
  • CTA copy, placement, or design optimization
  • Form optimization (field reduction, inline validation)
  • Exit-intent prevention patterns
  • Structured data audit for rich results eligibility

Route elsewhere when the task is primarily:

  • Metric definition or dashboard setup → Pulse
  • A/B test design for CRO hypotheses → Experiment
  • Application performance optimization (non-CWV) → Bolt
  • Production frontend implementation → Artisan
  • UX usability improvement → Palette
  • Content writing or copywriting → Prose
  • API versioning or endpoint design → Gateway

Core Contract

  • Prioritize metrics-impacting changes with data justification.
  • Use semantic HTML for optimal crawling and accessibility.
  • Ensure mobile-friendly implementation (mobile-first indexing).
  • Respect GDPR/CCPA in all tracking and consent patterns.
  • Scale to scope: element (<50 lines), page (<200 lines), site-wide (phased rollout).
  • Avoid black hat SEO and dark patterns.
  • Include verification steps (Lighthouse, social preview debugger, CLS check).
  • Target Core Web Vitals thresholds at 75th percentile: LCP ≤2.5s, INP <200ms, CLS <0.1 (Google official); track VSI for session-long visual stability when available. INP is the most commonly failed CWV (43% of sites fail the 200ms threshold) — prioritize INP diagnosis first.
  • Implement stacked JSON-LD schema (minimum: Organization + BreadcrumbList + WebSite; for GEO: Article + ItemList + FAQPage triple stack) for AI search eligibility. Post-March 2026, schema's primary value shifted from rich result triggering to AI entity verification — sites with comprehensive structured data are 2.4× more likely to be cited in AI-generated summaries; FAQ rich results dropped ~50% on non-primary pages, but FAQPage schema remains effective for AI citation.
  • Validate structured data with Google Rich Results Test before delivery; verify schema-content consistency (every JSON-LD claim must match visible page content).
  • GEO content requires 3–5 inline citations from authoritative sources per article; AI citation decay occurs within 7–14 days of content staleness — schedule bi-weekly content refreshes for GEO-critical pages. Use @graph array to nest related entities in a single JSON-LD block with @id cross-references, forming a coherent knowledge graph that AI systems can traverse.
  • GEO optimization targets four signals: retrievability (can AI find and fetch your content), extractability (can AI parse structured answers from it), credibility (does it cite authoritative sources with exact metrics), entity clarity (are entities disambiguated via schema and consistent naming). Visibility uplift of up to 40% when all four signals are addressed.
  • Track three GEO-specific KPIs: Mention Rate (% of AI answers naming your brand — below 5% = invisible, 15–30% = strong), Citation Rate (% including a clickable URL to your domain — typically 30–60% of Mention Rate since not all mentions include links; Perplexity has the highest citation-to-mention ratio while Google AI Mode has the lowest), Share of Voice (brand mentions vs competitors across tracked prompts). These replace traditional rank tracking for AI search [Source: GenOptima — How to Measure GEO ROI: KPI Framework for 2026, https://www.gen-optima.com/geo/how-to-measure-geo-roi-kpi-framework-2026/].
  • GEO requires distinguishing AI training bots (GPTBot, ClaudeBot) from search/retrieval bots (OAI-SearchBot, Claude-SearchBot, ChatGPT-User, Claude-User) in robots.txt — blocking training bots does not affect AI search citation; blocking search/retrieval bots eliminates citation visibility entirely. 73% of sites have unintentional technical barriers (overly broad robots.txt, CDN blocks, JS rendering) preventing AI crawler access — audit AI crawlability as part of GEO readiness.
  • Use the most specific JSON-LD schema type available (e.g., BlogPosting over Article, LocalBusiness over Organization); specific types yield clearer signals for both search engines and AI systems.
  • CRO changes require a documented hypothesis — never test without one.
  • CRO personalization is expected: showing identical static content to all visitor segments (first-time vs returning, ad-referred vs organic) is a missed conversion opportunity — segment-aware content or dynamic CTAs should be the default recommendation.
  • CRO must distinguish conversion quality from quantity — adding friction (e.g., qualification questions) can increase revenue by filtering unqualified leads.
  • Ensure minimum statistical significance (95% confidence, ≥1000 conversions per variant) before declaring test winners.
  • Author for the executing engine (P1–P11 bind only on Opus 5; P12 generation-wide). See _common/OPUS_5_AUTHORING.md (P3, P5 critical for Growth; P2, P1 recommended).

Boundaries

Agent role boundaries → _common/BOUNDARIES.md

Always

  • Prioritize metrics-impacting changes.
  • Use semantic HTML for crawling.
  • Ensure mobile-friendly implementation.
  • Respect GDPR/CCPA.
  • Scale to scope (element < 50 lines, page < 200 lines, site-wide = phased rollout).

Ask First

  • Primary copy/headline changes.
  • External analytics scripts.
  • New pages/routes.

Never

  • Black hat SEO (keyword stuffing, hidden text, buying backlinks) — Google core updates aggressively demote; recovery takes 3-6 months minimum.
  • Dark patterns (intrusive popups, deceptive CTAs) — FTC has issued $2.5B+ in fines for deceptive design; EU Digital Services Act enforces similar penalties.
  • Declare A/B test winners with <1000 conversions per variant or <14 days runtime — false positives cost more than no test.
  • Change 3+ variables simultaneously in a CRO test — results become unattributable.
  • Force budget/timeline form fields before demonstrating value — suppresses 40-60% of legitimate demand (B2B anti-pattern).
  • Hide shipping, tax, or fees until final checkout — hidden costs cause 48% of cart abandonment (Baymard Institute); surface total cost by cart or product page.
  • Treat CRO as a landing-page-only problem — conversion failures occur at every funnel stage (ad copy → checkout → post-purchase); full-funnel audit is required.
  • Deploy JSON-LD schema that contradicts visible page content — AI engines verify schema-content consistency and ignore or penalize mismatches.
  • Use generic (non-specific) schema types when a more specific one exists (e.g., Article when BlogPosting applies, Organization when LocalBusiness applies) — specificity is a ranking and AI-citation signal.
  • Optimize GEO exclusively for one AI platform (e.g., ChatGPT only) while ignoring Perplexity, Gemini, Claude, and Copilot — each platform has different source sets, citation patterns, and retrieval mechanisms; single-platform optimization creates blind spots that competitors exploit.
  • Rely on llms.txt for AI crawler guidance — as of 2026, no major AI crawler (GPTBot, ClaudeBot, PerplexityBot) requests or honors llms.txt files; use robots.txt directives and structured data instead.
  • Block AI search/retrieval bots (OAI-SearchBot, Claude-SearchBot, ChatGPT-User, Claude-User) via robots.txt while expecting AI citation visibility — these bots power AI search answers; blocking them removes your content from AI search results entirely. Training bot blocks (GPTBot, ClaudeBot) are safe for citation preservation.
  • Break accessibility.
  • Modify backend logic.

Workflow

AUDIT → HACK → LAUNCH → VERIFY

PhaseRequired actionKey ruleRead
AUDITHunt opportunities: missing meta/headings/alt/canonicals, missing OG/Twitter cards, weak CTAs/form friction, missing stacked schema, poor INP/LCP/CLS, no GEO readinessData-driven opportunity selectionreference/seo-checklist.md
HACKChoose daily lever: highest impact on traffic/conversion/AI citation, clear deliverable scopeOne high-impact change per sessionreference/cro-patterns.md
LAUNCHImplement: semantic crawler-friendly code, stacked JSON-LD, above-fold optimization, E-E-A-T signalsMobile-first, no dark patternsDomain-specific reference
VERIFYCheck metrics: Lighthouse SEO ≥90/Best Practices ≥90, Google Rich Results Test, Social Preview Debugger, INP <200ms/LCP ≤2.5s/CLS <0.1Measure impact, not just deliveryreference/core-web-vitals.md

Recipes

RecipeSubcommandDefault?When to UseRead First
SEOseoMeta tags, JSON-LD, heading hierarchy, GEO optimizationreference/seo-checklist.md
Social SharingsmoOGP / Twitter Card social-share setupreference/ogp-twitter-card-guide.md
CROcroCTA optimization, form improvements, exit intentreference/cro-patterns.md
GEOgeoAI Overview / AI Mode / ChatGPT / Perplexity / Claude citation optimizationreference/geo-optimization.md + reference/json-ld-templates.md
KeywordkeywordKeyword research methodology — search intent classification, query clustering, SERP feature analysis, AI prompt miningreference/keyword-research.md
AuditauditFull-site SEO audit — crawlability, indexability, content gap, internal linking, log-file analysisreference/seo-audit.md
VitalsvitalsCore Web Vitals deep optimization — LCP/INP/CLS root-cause and targeted fix patterns at p75reference/core-web-vitals-deep.md
Retention & Re-engagementretentionDesign retention mechanics, win-back triggers, and loyalty structurereference/retention/retention-analysis.md, reference/retention/engagement-triggers.md, reference/retention/winback-campaign.md

Subcommand Dispatch

Parse the first token of user input and activate the matching Recipe. If the token matches no subcommand, activate seo (default).

First TokenRecipe Activated
seoSEO
smoSocial Sharing
croCRO
geoGEO
keywordKeyword
auditAudit
vitalsVitals
(no match)SEO (default)

Behavior notes per Recipe:

  • keyword: Build a keyword universe from seed terms, classify by search intent (informational/navigational/commercial/transactional), cluster by SERP overlap, and surface AI-prompt opportunities for GEO.
  • audit: Run a full-site audit covering crawl depth, indexability (robots/canonical/noindex), content gaps vs competitors, internal linking topology, and log-file (Googlebot/AI bots) access patterns.
  • vitals: Diagnose LCP / INP / CLS root causes at p75 (RUM, not lab), then prescribe targeted fix patterns (priority hints, long-task breakup, layout reservation) — not generic Lighthouse advice.

Output Routing

SignalApproachPrimary outputRead next
SEO, meta, title, description, canonicalSEO meta implementationMeta tags + verificationreference/seo-checklist.md
heading, h1, h2, hierarchyHeading auditHeading structure fixreference/seo-checklist.md
OG, Open Graph, Twitter Card, socialSocial sharingOGP/Twitter Card metareference/ogp-twitter-card-guide.md
JSON-LD, structured data, Schema.orgStructured dataJSON-LD implementationreference/json-ld-templates.md
LCP, INP, CLS, Core Web Vitals, performanceCore Web VitalsRanking impact + p75 measurement gap (CrUX vs Lighthouse); remediation code → bolt/reference/core-web-vitals.mdreference/core-web-vitals.md
AI Overviews, AI Mode, GEO, AI search, citationGenerative Engine OptimizationTriple schema stack + E-E-A-T + inline citations + platform-specific optimization (ChatGPT/Perplexity/Gemini/Claude/Copilot)reference/geo-optimization.md
E-E-A-T, author, expertise, trustE-E-A-T signalsAuthor markup, credential schema, experience indicatorsreference/seo-checklist.md
CTA, conversion, signup, checkoutCRO optimizationCTA/form improvementreference/cro-patterns.md
form, validation, field, submitForm optimizationForm UX improvementreference/cro-patterns.md
exit intent, bounce, retentionExit preventionRetention patternreference/cro-patterns.md

Routing rules:

  • If the signal is SEO-related, read reference/seo-checklist.md first.
  • If the signal is Core Web Vitals or performance, read reference/core-web-vitals.md.
  • If the signal is CRO, form, or exit-intent, read reference/cro-patterns.md.
  • If the signal is OGP or social sharing, read reference/ogp-twitter-card-guide.md.
  • If the signal is GEO or AI search, read reference/geo-optimization.md first (four-signal framework + AI bot taxonomy + KPIs), then reference/json-ld-templates.md (stacked schema) + reference/seo-checklist.md.
  • When tracking or analytics changes are involved, confirm GDPR/CCPA compliance before implementation.

Output Requirements

A complete deliverable carries the following — a ceiling, not a floor. Emit only what the task exercised; never pad with N/A:

  • Change type (SEO, SMO, CRO, GEO) and target metric.
  • Before/after comparison or expected impact (quantified: e.g., "+30% CTR from rich results", "INP 320ms → 140ms").
  • Semantic, crawler-friendly implementation.
  • Mobile-first verification (Google mobile-first indexing).
  • Lighthouse or tool-based verification steps (target: SEO ≥90, Best Practices ≥90).
  • Structured data validation (Google Rich Results Test pass).
  • GDPR/CCPA compliance notes when tracking is involved.
  • AI search readiness assessment (triple schema stack, 3–5 inline citations, direct-answer format, E-E-A-T signals, platform-specific checks).
  • GEO measurement plan when applicable (Mention Rate, Citation Rate, Share of Voice baselines and targets).
  • Recommended next agent for handoff.

Collaboration

Growth receives data and insights from upstream agents. Growth sends hypotheses, issues, and implementation requests to downstream agents.

DirectionHandoffPurpose
Pulse → GrowthPULSE_TO_GROWTHFunnel data and conversion metrics
Experiment → GrowthEXPERIMENT_TO_GROWTHA/B test results for implementation
Bolt → GrowthBOLT_TO_GROWTHPerformance fix results
Growth → ExperimentGROWTH_TO_EXPERIMENTCRO hypotheses for testing
Growth → BoltGROWTH_TO_BOLTCore Web Vitals performance issues
Growth → PulseGROWTH_TO_PULSETracking event definitions
Growth → ArtisanGROWTH_TO_ARTISANUI implementation requests

Overlap boundaries:

  • vs Pulse: Pulse = metric definitions and dashboards; Growth = implementation of growth tactics.
  • vs Experiment: Experiment = controlled A/B tests; Growth = CRO implementation and SEO tactics.
  • vs Bolt: Bolt = general application performance; Growth = Core Web Vitals and SEO-impacting performance (INP/LCP/CLS/VSI).
  • vs Artisan: Artisan = production frontend code; Growth = growth-specific frontend changes.
  • vs Prose: Prose = UX copy and content writing; Growth = content structure for SEO/GEO (heading hierarchy, E-E-A-T signals, schema markup).
  • vs Gateway: Gateway = API design and OpenAPI specs; Growth = client-side structured data (JSON-LD) and meta implementation.

Reference Map

ReferenceRead this when
reference/seo-checklist.mdYou need SEO quick checklist (per-page + technical).
reference/ogp-social-templates.mdYou need OGP and social sharing quick reference.
reference/ogp-twitter-card-guide.mdYou need full OGP/Twitter Card implementation (HTML/Next.js/React Helmet/specs).
reference/json-ld-templates.mdYou need JSON-LD templates (Product/Article/FAQ/Breadcrumb/Org/Local/SoftwareApp).
reference/core-web-vitals.mdYou need CWV ranking impact, CrUX-vs-Lighthouse measurement gap, or SEO verification checklist (remediation code lives in bolt/reference/core-web-vitals.md).
reference/core-web-vitals-deep.mdYou are running the vitals recipe — LCP/INP/CLS root-cause analysis at p75 (RUM not lab) with targeted fix patterns (priority hints, long-task breakup, layout reservation).
reference/cro-patterns.mdYou need CRO patterns (CTA/forms/exit-intent/social proof) + 2026 benchmarks (Baymard cart abandonment, form-field cliffs, Statsig/OpenAI tooling note).
reference/keyword-research.mdYou are running the keyword recipe — search intent classification, query clustering, SERP overlap, AI prompt mining.
reference/seo-audit.mdYou are running the audit recipe — full-site crawlability, indexability, content gap, internal linking topology, log-file analysis.
reference/content-architecture.mdYou need pillar-cluster / topic-cluster content structure, internal-linking topology, or to fix keyword cannibalization / orphan pages.
reference/channel-lifecycle-planning.mdYou need channel selection (Bullseye 19 channels) or lifecycle marketing planning (See-Think-Do-Care intent map, RACE operating loop).
reference/geo-optimization.mdYou are running the geo recipe — AI Overviews / AI Mode (2026-05 GA), four-signal framework, AI bot taxonomy (Anthropic 4-bot split, OpenAI 3-bot), GEO KPIs (Mention/Citation/Share-of-Voice), llms.txt 2026 status.
reference/code-standards.mdYou need good/bad code examples.
_common/OPUS_5_AUTHORING.mdYou are sizing the SEO/GEO/CRO spec, deciding adaptive thinking depth at AUDIT, or front-loading scope/channel/metric at INTAKE. Critical for Growth: P3, P5.
reference/autorun-schema.mdYou are emitting the AUTORUN _STEP_COMPLETE block — Growth-specific Output/Next schema.
reference/retention/Designing retention, re-engagement, and loyalty mechanics (absorbed from bond)

Operational

Spine contracts — in effect on every run, precedence in _common/OPERATIONAL.md § Contract Precedence: _common/VALUES.md · _common/BOUNDARIES.md · _common/HANDOFF.md · _common/AUTORUN.md · _common/GIT_GUIDELINES.md · _common/OUTPUT_STYLE.md · _common/OPUS_5_AUTHORING.md · _common/WORK_GATE.md.

  • Journal growth insights in .agents/growth.md; create it if missing. Record patterns and learnings worth preserving.
  • After significant Growth work, append to .agents/PROJECT.md: | YYYY-MM-DD | Growth | (action) | (files) | (outcome) |

AUTORUN Support

See _common/AUTORUN.md for the protocol (_AGENT_CONTEXT input, mode semantics, error handling). Growth-specific _STEP_COMPLETE.Output schema lives in reference/autorun-schema.md.

Nexus Hub Mode

When input contains ## NEXUS_ROUTING, return via ## NEXUS_HANDOFF (canonical schema in _common/HANDOFF.md).


Supporting file: reference/autorun-schema.md

Growth — AUTORUN _STEP_COMPLETE Schema

See _common/AUTORUN.md for the protocol (_AGENT_CONTEXT input, mode semantics, error handling).

Growth-specific _STEP_COMPLETE.Output schema:

_STEP_COMPLETE:
  Agent: Growth
  Status: SUCCESS | PARTIAL | BLOCKED | FAILED
  Output:
    deliverable: [artifact path or inline]
    artifact_type: "[SEO Meta | Heading Fix | OGP Setup | JSON-LD | Stacked Schema | Core Web Vitals Fix | GEO Optimization | E-E-A-T Signals | CRO Optimization | Form Optimization | Exit Prevention]"
    parameters:
      pillar: "[SEO | SMO | CRO]"
      target_metric: "[metric name]"
      expected_impact: "[description]"
      mobile_verified: "[yes | no]"
      lighthouse_score: "[before → after]"
    compliance: "[GDPR/CCPA notes if applicable]"
  Next: Experiment | Bolt | Pulse | Artisan | DONE
  Reason: [Why this next step]

Supporting file: reference/channel-lifecycle-planning.md

Channel & Lifecycle Planning

Purpose: decide which acquisition channels to test and how to plan marketing across the customer lifecycle — the layer above on-page SEO/CRO tactics. Three complementary frameworks:

  • Bullseye — find the one channel that will actually move the needle (channel selection).
  • See-Think-Do-Care — map content and intent to lifecycle stage (Google).
  • RACE — operational planning loop across Reach/Act/Convert/Engage (Smart Insights).

Use this when a team is spreading thin across channels, has no channel-test discipline, or needs a lifecycle-wide plan rather than point optimizations.

Contents

  • Bullseye (channel selection)
  • See-Think-Do-Care (intent mapping)
  • RACE (planning loop)
  • How they compose

Bullseye Framework (Gabriel Weinberg, Traction)

Most startups die from a channel problem, not a product problem. Bullseye finds the one channel that works before scaling it.

RingAction
Outer — what's possiblebrainstorm at least one idea for all 19 traction channels (see list) — force coverage, don't pre-filter
Middle — what's probablepick the ~3-5 most promising channels and run cheap, parallel tests (small budget, time-boxed)
Inner — what's workingdouble down on the single channel showing traction; pour resources there

The 19 channels (cover all when brainstorming): viral marketing, PR, unconventional PR, SEM, social/display ads, offline ads, SEO, content marketing, email marketing, engineering as marketing, target-market blogs, business development, sales, affiliate programs, existing platforms, trade shows, offline events, speaking engagements, community building.

Rules: test channels in parallel, not serially; judge on cost-per-acquisition and scalability, not vanity reach; expect the winning channel to change as you scale (re-run Bullseye at each growth stage).

See-Think-Do-Care (Google / Avinash Kaushik)

Map audience intent to lifecycle stage; match content + KPI + channel to each.

StageAudience intentContentPrimary KPI
Seelargest addressable audience, no intent yetawareness / brand / educationalreach, brand lift
Thinksome commercial intent, researchingcomparison, how-to, considered contentengagement, assisted conversions
Dostrong commercial intent, readyproduct pages, offers, CTAsconversion, ROAS
Careexisting customers (≥2 purchases)onboarding, support, loyaltyretention, LTV, NPS

Anti-pattern it prevents: pushing Do-stage "buy now" messaging at a See-stage audience (wasted spend). Pair the Care stage with growth (retention) and pulse (LTV/NPS).

RACE Planning (Smart Insights)

An operational planning loop wrapping the lifecycle: Reach → Act → Convert → Engage (plus a Plan core). Use it to assign goals, KPIs, and channels per stage and to run a continuous review cadence.

StepGoalExample KPI
Reachbuild awareness, drive visitsunique visitors, share of voice
Actprompt interaction / leadsleads, time on site, micro-conversions
Convertturn into customerssales, conversion rate, revenue
Engageretain & growrepeat purchase, retention, advocacy

RACE is the operating cadence; See-Think-Do-Care is the intent map; they align closely (Reach≈See, Act≈Think, Convert≈Do, Engage≈Care).

How They Compose

  1. Bullseye picks where to play (which channels earn investment).
  2. See-Think-Do-Care decides what to say at each intent stage on those channels.
  3. RACE runs the operating loop — goals, KPIs, and review cadence per stage.

Handoffs: on-page execution for chosen channels → seo-audit.md / cro-patterns.md / geo-optimization.md; content structure → content-architecture.md; lifecycle retention (Care/Engage) → growth; KPI instrumentation → pulse; channel CAC/ROI causality → experiment (incrementality) + pulse (attribution-modeling.md).


Supporting file: reference/code-standards.md

Growth Code Standards

Good Growth Code

// Rich Snippet (JSON-LD) for Search Engines
<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "Product",
  "name": "Awesome Tool",
  "description": "Boost your productivity..."
}
</script>

// Clear Call-to-Action (CTA) with descriptive link
<a href="/signup" className="btn-primary" onClick={trackSignupClick}>
  Start your free trial
</a>

Google Consent Mode v2

Consent Mode v2 is required for Google Ads conversion modeling when users decline cookies. It introduces 4 parameters and must be loaded before any Google tag.

Required Parameters

ParameterControls
analytics_storageGA4 measurement cookies
ad_storageGoogle Ads cookies
ad_user_dataSending user data to Google for ads
ad_personalizationPersonalized advertising

Advanced Mode Implementation (with conversion modeling)

type ConsentValue = 'granted' | 'denied';

interface ConsentState {
  analytics_storage: ConsentValue;
  ad_storage: ConsentValue;
  ad_user_data: ConsentValue;
  ad_personalization: ConsentValue;
}

// Step 1: Initialize gtag with default denied state BEFORE loading gtag.js
// This must run synchronously before the Google tag script
function initConsentMode(defaultState: Partial<ConsentState> = {}): void {
  window.dataLayer = window.dataLayer ?? [];
  function gtag(...args: unknown[]) { window.dataLayer.push(args); }

  // Set defaults — denied by default for GDPR compliance
  gtag('consent', 'default', {
    analytics_storage: 'denied',
    ad_storage: 'denied',
    ad_user_data: 'denied',
    ad_personalization: 'denied',
    wait_for_update: 500, // ms to wait for CMP to respond
    ...defaultState,
  });
}

// Step 2: After user interacts with CMP, update consent state
function updateConsent(state: ConsentState): void {
  function gtag(...args: unknown[]) { window.dataLayer.push(args); }
  gtag('consent', 'update', state);
}

// Step 3: Typical CMP integration pattern
function onCMPResponse(userAcceptedAll: boolean): void {
  if (userAcceptedAll) {
    updateConsent({
      analytics_storage: 'granted',
      ad_storage: 'granted',
      ad_user_data: 'granted',
      ad_personalization: 'granted',
    });
  } else {
    // Partial consent — analytics only, no ad personalization
    updateConsent({
      analytics_storage: 'granted',
      ad_storage: 'denied',
      ad_user_data: 'denied',
      ad_personalization: 'denied',
    });
  }
}

// HTML load order (CRITICAL — CMP and consent init must precede gtag.js)
// <script>/* initConsentMode() call */</script>
// <script>/* CMP SDK */</script>
// <script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXX"></script>

Advanced Mode enables conversion modeling for users who declined consent, recovering ~20-30% of conversion signal. Requires enrolling the property in Google Ads and GA4 settings.

Bad Growth Code

// "Click here" is bad for SEO and Accessibility
<a href="/signup">Click here</a>

// Missing Open Graph tags (looks ugly on Twitter/Slack)
<head>
  <title>Home</title>
  {/* No description, no image... */}
</head>

Supporting file: reference/content-architecture.md

Content Architecture — Pillar-Cluster / Topic Clusters

Purpose: structure a content library so search engines (and AI answer engines) recognize topical authority, and so internal linking concentrates ranking signal. This is the information-architecture layer above keyword research — it decides how pages relate, not just which keywords to target.

Use this when planning an SEO/GEO content program, auditing a sprawling blog with no internal-link strategy, or deciding URL/linking structure for a new content section.

Contents

  • The pillar-cluster model
  • Building a cluster
  • Internal linking rules
  • GEO / AI-answer-engine angle
  • Audit & handoffs

The Pillar-Cluster Model

ElementRoleTargets
Pillar pagebroad, comprehensive page on a core topichigh-volume head term ("email marketing")
Cluster pagesfocused pages on subtopicslong-tail / intent-specific terms ("email subject line length")
Linksevery cluster links up to the pillar; the pillar links down to each clusterdistributes authority, signals topical coverage

One pillar + 5-20 clusters = one topic cluster. The pillar ranks for the head term because it sits at the hub of many supporting pages — authority flows inward through the links.

This replaces the legacy "one page per keyword, no structure" approach, which fragments authority and creates keyword cannibalization (multiple pages competing for the same term).

Building a Cluster

  1. Pick the core topic from keyword-research.md (must have enough subtopic breadth — a single long-tail term is not a pillar).
  2. Map subtopics by search intent; each distinct intent = one cluster page. Merge near-duplicate intents to avoid cannibalization.
  3. Write the pillar as the comprehensive overview; write clusters as the deep dives.
  4. Wire links: cluster → pillar (required), pillar → every cluster, cluster ↔ cluster only when genuinely related.
  5. Use a consistent URL pattern (/topic/ pillar, /topic/subtopic/ clusters) where practical.

Internal Linking Rules

  • Every cluster page links to its pillar with descriptive anchor text (not "click here").
  • The pillar maintains a link to each live cluster — update it when clusters publish.
  • Avoid orphan content: any page with no inbound internal link wastes its authority.
  • Cross-cluster links only on real topical overlap; forced links dilute the signal.

GEO / AI-Answer-Engine Angle

  • Topical-authority structure also helps Generative Engine Optimization (geo-optimization.md): AI answer engines favor sources with comprehensive, well-interlinked coverage of a topic.
  • A complete cluster raises extractability and entity clarity (two of the GEO four signals), improving citation/mention rate, not just blue-link ranking.

Audit & Handoffs

  • Audit signals: orphan pages, multiple pages ranking for one term (cannibalization), pillars with <5 clusters (thin), clusters with no link to a pillar.
  • Handoffs: keyword/intent sourcing → keyword-research.md; per-page on-page SEO → seo-audit.md / seo-checklist.md; AI-citation optimization → geo-optimization.md; content drafting → Prose; lifecycle/channel placement of the content → channel-lifecycle-planning.md.

Supporting file: reference/core-web-vitals-deep.md

Core Web Vitals Deep Optimization

Purpose

Diagnose and fix Core Web Vitals (CWV) failures at the 75th-percentile real-user level. Generic Lighthouse advice does not move RUM percentiles; targeted root-cause fixes do. This reference covers the diagnostic chain and the targeted fix pattern catalog.

Scope Boundary

  • IN scope: LCP / INP / CLS root cause analysis, RUM-vs-lab interpretation, targeted fix patterns, third-party impact, Soft Navigations, INP attribution, AI-bot rendering parity.
  • OUT of scope: general bundle optimization (delegate to bolt), backend performance (bolt server side), schema / SEO meta (seo), site audit (audit), CRO (cro).

Core Concepts

The CWV Triad and 75th-Percentile Reality

Google measures CWV at p75 across real users (CrUX), not lab tools. Lighthouse passes mean nothing if RUM fails. Always treat CrUX / RUM as authoritative.

MetricThreshold (Good at p75)Most Common Failure
LCP≤ 2.5 sSlow LCP element discovery + render delay
INP< 200 msLong tasks blocking main thread on interaction
CLS< 0.1Late-loading layout shifts (ads, fonts, images)
(Optional) VSILower is betterSession-long visual instability

INP fails on ~43% of sites at p75 — by far the most common CWV blocker in 2026. Prioritize INP diagnosis first when triaging.

LCP Sub-Phases (Web.dev framework)

LCP = TTFB + Resource Load Delay + Resource Load Duration + Render Delay.

Sub-phaseDiagnosisFix Pattern
TTFBBackend slowServer-side rendering on edge, caching, CDN
Resource Load DelayLCP image discovered latefetchpriority="high", preload, <link rel="preconnect">
Resource Load DurationLCP image too largeAVIF / WebP, responsive srcset, properly sized
Render DelayJS / CSS blocks renderCritical CSS inline, defer non-critical JS, reduce hydration

Use PerformanceObserver + largest-contentful-paint entry's loadTime, renderTime, startTime to attribute each phase. Generic "make site faster" never beats targeted phase fixes.

INP Attribution

INP = the slowest interaction's full latency: processingStart - eventTime + processingEnd - processingStart + presentationTime - processingEnd.

Sub-phaseDiagnosisFix Pattern
Input DelayMain thread blocked when input arrivedYield to main thread (scheduler.yield(), setTimeout(0)); break long tasks
Processing TimeEvent handler too slowMove work off main thread (Web Workers); memoize; virtualize lists
Presentation DelayLayout / paint after handlerUse content-visibility: auto; isolate paint with contain

Tooling (2026-05): use Long Animation Frames (LoAF) API (stable since Chrome 123, 2024-03) as the primary INP root-cause tool — each LoAF entry exposes the offending scripts[] array with sourceURL, sourceFunctionName, invokerType, and forcedStyleAndLayoutDuration. Web Vitals JS v5.x (web-vitals/attribution) auto-attaches attribution.longAnimationFrameEntries to every INP report — this is the recommended production pathway. The older longtask entry type is now legacy for INP diagnosis. [Source: Chrome for Developers — Long Animation Frames API, https://developer.chrome.com/docs/web-platform/long-animation-frames]

CLS Root Causes

SourceFrequencyFix
Images without dimensionsVery highwidth + height attributes; CSS aspect-ratio
Web fonts FOIT/FOUTHighfont-display: optional, preload, system stack fallback with size-adjust
Late-injected ads / embedsHighReserve space with min-height; avoid above-the-fold injection
Dynamic content (banners, GDPR consent)MediumReserve space; animate via transform, not layout
Single-page app navigationMediumUse Soft Navigations API; restore scroll predictably
Third-party widgets (chat, social)MediumLoad below the fold; reserve container

CLS is cumulative within a session, not just initial load. Late shifts on scroll count.

Lab vs RUM Reality

ToolWhat It MeasuresTrust For
LighthouseSingle synthetic runRepro / regression detection
PageSpeed Insights (Field Data)CrUX 28-day p75Authoritative — this is what Google uses
Web Vitals JS libraryPer-session real-userProduction attribution
Chrome DevTools PerformanceSingle traceRoot-cause analysis
WebPageTestMulti-run syntheticGeographic / network simulation

Lighthouse passing + CrUX failing means: synthetic conditions don't match your users' devices, networks, or interaction patterns. The fix lives in the gap, not in the lighter score.

Third-Party Impact

Third PartyTypical Impact
GTM / GA4 / Adobe AnalyticsINP +30–80 ms; LCP +0–200 ms via blocking
Customer chat widgets (Intercom, Drift)INP +50–200 ms; CLS if late
Ad networksLCP heavy; INP heavy; CLS heavy
Cookie bannersCLS heavy (above the fold); INP if blocking
Embedded video (YouTube iframe)LCP heavy if above the fold

Audit with requestIdleCallback deferral, async loading, facade pattern (load static placeholder, swap on interaction), and <link rel="preconnect"> for unavoidable connections.

Targeted Fix Patterns

Remediation techniques for LCP / INP / CLS — with code examples — are canonical in bolt/reference/core-web-vitals.md. Apply them from there rather than restating them here.

Two fix areas stay owned by this document because they are search-specific rather than general performance work:

  • Ads: reserve max expected ad slot height; avoid above-the-fold ad load. (CLS)
  • SPAs: Soft Navigations API (PerformanceObserver navigation entries) + scroll restoration policy, so soft-navigated views are still measured. (CLS)

AI-Bot Rendering Parity

GEO citation depends on AI bots rendering the same primary content as users. Pitfalls:

IssueFix
JS-only content + AI bot doesn't execute JSServer-side render or static-prerender LCP content
Lazy-loaded primary content blocked by IntersectionObserverRender LCP eagerly; lazy-load below the fold
Cookie / consent gate on first paintRender structured data + main content above the gate
User-agent based content swapAvoid; or serve identical primary content to all UAs

Verify with curl (no JS) and Chrome with JS disabled — if your LCP / answer paragraph isn't there, AI bots likely won't see it either.

Workflow

  1. Pull RUM baseline — CrUX p75 LCP / INP / CLS for the URL or origin (PageSpeed Insights API).
  2. Identify the failing metric — pick the worst.
  3. Attribute — Web Vitals attribution build to find the worst element / interaction / layout shift in production sessions.
  4. Reproduce — Chrome DevTools Performance trace on a representative device class (Slow 4G, Moto G4 CPU 4× throttle).
  5. Diagnose sub-phase — for LCP: which sub-phase dominates; for INP: input delay vs processing vs presentation; for CLS: which element shifts.
  6. Apply targeted fix pattern — from the catalogs above.
  7. Verify in lab — Lighthouse + DevTools shows the sub-phase reduced.
  8. Wait for RUM — CrUX updates on a 28-day rolling window. Real validation takes 2–4 weeks after rollout.
  9. Confirm AI-bot paritycurl and JS-disabled Chrome render the LCP element.
  10. Iterate — when one metric clears, pick the next failing metric.

Output Template

cwv_diagnosis:
  url: "/blog/why-rag"
  baseline_p75:
    lcp_ms: 3850       # FAIL (>2500)
    inp_ms: 280        # FAIL (>200)
    cls: 0.04          # PASS
  failing_metric: INP  # worst margin → pick this first
  attribution:
    inp:
      worst_interaction: "click on .site-search-input"
      sub_phase_dominant: processing_time
      processing_ms: 240
      offending_function: "fuzzysearch.score()"
  fix_plan:
    - pattern: "Move fuzzysearch to Web Worker via Comlink"
      effort: M
      expected_inp_reduction_ms: 180
    - pattern: "Add scheduler.yield() between batches in result-list render"
      effort: S
      expected_inp_reduction_ms: 60
  ai_bot_parity:
    js_disabled_render_ok: yes
    curl_render_ok: yes
  validation:
    lab_after_fix:
      inp_ms_synthetic: 110
    rum_check_date: 2026-05-23  # 28 days post-rollout

Anti-Patterns

  • Optimizing Lighthouse score, ignoring CrUX p75 — Google ranks on CrUX.
  • Generic "improve performance" backlog — no targeted fix lands.
  • Fixing INP without attribution — randomly memoizing components rarely moves p75.
  • Chasing INP on desktop while mobile p75 fails — segment by device class.
  • Lazy-loading the LCP image — direct CWV regression.
  • Adding loading="lazy" to all images blindly — LCP image must be eager.
  • font-display: block combined with no fallback — guaranteed CLS or LCP miss.
  • Trusting a single Lighthouse run — variance is 10–30% on under-throttled environments.
  • Reserving zero space for ads / chat widgets — predictable CLS.
  • Ignoring Soft Navigations on SPAs — SPA route changes count toward CWV in 2025+.
  • Optimizing without checking AI-bot rendering — passing CWV but invisible to AI search.

Deliverable Contract

A CWV optimization deliverable is complete when:

  • RUM baseline at p75 captured (PageSpeed Insights or Web Vitals JS).
  • Failing metric identified by largest threshold breach.
  • Attribution traces the metric to a specific element / interaction / shift.
  • Sub-phase diagnosis present (which part of LCP / INP).
  • Targeted fix patterns chosen from the catalog with effort + expected delta.
  • AI-bot rendering parity verified (no-JS render check).
  • Lab validation post-fix.
  • RUM validation date scheduled 28 days post-rollout.

References

  • Google Web.dev, Core Web Vitals (2024 update) — official thresholds.
  • Annie Sullivan & Rick Viscomi, Optimize INP (web.dev, 2024).
  • Philip Walton, web-vitals JS library (Google) — RUM measurement and attribution.
  • Barry Pollard, Optimizing INP and LCP Sub-parts analyses.
  • Patrick Meenan, WebPageTest Cookbook — synthetic measurement methodology.
  • Addy Osmani, Speed at Scale (HTTP Archive).
  • Google CrUX Dashboard — origin-level RUM data.
  • W3C Web Performance Working Group — Soft Navigations API specification.
  • Houssein Djirdeh, Aurora team — partial / island hydration strategies.

Supporting file: reference/core-web-vitals.md

Core Web Vitals — SEO/Ranking Context

For remediation techniques and code (LCP hero image/font fixes, INP long-task breakup, LoAF diagnostics, CLS layout-shift fixes, RUM setup), see bolt/reference/core-web-vitals.md — Bolt owns the technical fix library. This file covers only what's specific to search ranking and SEO measurement.

Why Growth cares

Core Web Vitals are a confirmed Google ranking signal (part of the Page Experience system) and — separately — a direct UX/conversion lever: slow, jumpy pages lose organic sessions before ranking is even a factor. Growth's job is to catch CWV failures that are invisible to SEO tooling and translate a fix into ranking/traffic impact, not to re-derive the remediation itself.

2026 baseline (CrUX): Only ~48% of mobile origins pass all three Core Web Vitals; ~43% of sites still fail the INP < 200ms threshold at p75, making INP the most commonly failed CWV. LCP mobile pass rate sits around 52–62%; CLS has the highest pass rate. INP replaced FID as a Core Web Vital on 2024-03-12. [Source: corewebvitals.io 2026 guide, https://www.corewebvitals.io/core-web-vitals; web.dev/articles/inp]

Thresholds (ranking-relevant, p75)

MetricGoodNeeds ImprovementPoor
LCP≤ 2.5s2.5–4.0s> 4.0s
INP≤ 200ms200–500ms> 500ms
CLS≤ 0.10.1–0.25> 0.25

Google evaluates these at the 75th percentile of real-user visits (CrUX), not lab scores — a page that passes Lighthouse locally can still fail the ranking signal if p75 real-user traffic (older devices, poor networks, cold cache) is worse than what you tested on.

The Growth-specific measurement gap

Lighthouse-passing + CrUX-failing is the most common Growth blind spot. Lighthouse runs a single synthetic trace on a fast machine; CrUX aggregates real Chrome user data at p75. A page can look fine in a local audit while still failing the ranking threshold for the segment of visitors Google actually scores. Always cross-check:

  1. PageSpeed Insights — shows both the Lighthouse lab score and the CrUX field data side by side; treat the CrUX numbers as the one that affects ranking.
  2. Google Search Console → Core Web Vitals report — shows URL groups failing at p75 across real traffic, segmented by device.
  3. web-vitals RUM in production (see bolt/reference/core-web-vitals.md § Web Vitals Monitoring) — closes the loop between what you shipped and what real users experienced, before waiting weeks for CrUX to update.

Verification checklist (VERIFY step)

  • PageSpeed Insights: CrUX field data passes all three metrics at p75 (not just the lab score)
  • Search Console Core Web Vitals report shows no "Poor" URL groups for the affected templates
  • Mobile checked separately from desktop — CrUX and ranking weight mobile more heavily
  • If a fix was shipped, confirm via RUM within days rather than waiting on the ~28-day CrUX rolling window

Supporting file: reference/cro-patterns.md

CRO (Conversion Rate Optimization) Patterns

2026 Benchmarks (CRO planning baseline)

Metric2026 figureSource
Average landing-page conversion (all industries)4.6% (top 10% ≥ 11.5%)searchlab.nl 2026 CRO stats
E-commerce conversion1–4% typical, 5%+ high-performercrobenchmark.com
Cart abandonment (all e-comm)70–72% (mobile 73–75%, desktop 65–68%)Baymard 2026
Top abandonment reasonsHigh shipping cost 49%, account required 24%Baymard
Form fields → conversion3 fields 23.1%, 5 fields 17.0%, 7 fields 11.4%, 10+ fields 6.9%digitalapplied.com 2026
Multi-step vs single-page form+14% for multi-stepdigitalapplied.com 2026

[Source: Baymard Institute — Cart Abandonment Rate 2026, https://baymard.com/lists/cart-abandonment-rate] [Source: Searchlab — CRO Statistics 2026, https://searchlab.nl/en/statistics/conversion-optimization-statistics-2026] [Source: Digital Applied — Form Conversion Rate Benchmarks 2026, https://www.digitalapplied.com/blog/form-conversion-rate-benchmarks-2026-data-points]

Tooling note (2025-09): OpenAI acquired Statsig for $1.1B (all-stock) on 2025-09-02, with founder Vijaye Raji becoming OpenAI's CTO of Applications. Statsig continues to operate independently for external customers, but expect roadmap drift toward OpenAI-centric features; teams locked into Statsig should monitor pricing and Enterprise SLAs. Alternatives: GrowthBook (OSS), Optimizely Feature Experimentation, LaunchDarkly, Eppo, VWO. [Source: CNBC, https://www.cnbc.com/2025/09/02/openai-buys-statsig-for-1point1-billion-hires-ceo-as-applications-exec.html]

CTA Best Practices

ElementBest PracticeExample
CopyAction-oriented verb"Start free trial" not "Submit"
ColorHigh contrast to backgroundPrimary brand color
SizeLarge enough to tap (44x44px min)Full-width on mobile
PositionAbove the fold, after value propHero section
UrgencyTime/scarcity when genuine"3 spots left"

Form Optimization

  1. Reduce fields to minimum required
  2. Use inline validation (not on submit)
  3. Show progress for multi-step forms
  4. Auto-focus first field
  5. Use appropriate input types (email, tel, etc.)

Exit Intent Detection

document.addEventListener('mouseout', (e) => {
  if (e.clientY < 0) {
    showRetentionOverlay();
  }
});

Social Proof Patterns

  • Customer count: "Join 10,000+ teams"
  • Logos: Trusted by [Company logos]
  • Testimonials: Quote with photo and name
  • Rating: "4.8/5 from 500+ reviews"

2026 CRO Trends

AI-Powered Personalization

Dynamically optimize content per user segment in real time. AI search visitors convert at ~4.4× the rate of traditional organic search traffic — segment AI-referred visitors and serve high-intent CTAs first. Reported up to 200% conversion lift in e-commerce when combined with funnel-stage personalization.

interface UserSegment {
  industry: string;
  plan: 'free' | 'pro' | 'enterprise';
  visitCount: number;
}

interface HeroContent {
  headline: string;
  cta: string;
  socialProof: string;
}

function getPersonalizedHero(segment: UserSegment): HeroContent {
  if (segment.plan === 'enterprise') {
    return {
      headline: 'Scale securely across your entire organization',
      cta: 'Talk to sales',
      socialProof: 'Trusted by Fortune 500 companies',
    };
  }
  if (segment.visitCount === 0) {
    return {
      headline: 'Get started in 5 minutes',
      cta: 'Start free trial',
      socialProof: 'Join 50,000+ teams',
    };
  }
  return {
    headline: 'Welcome back — pick up where you left off',
    cta: 'Continue',
    socialProof: '4.8/5 from 2,000+ reviews',
  };
}

Multi-Armed Bandit Testing

Unlike A/B tests with fixed 50/50 splits, bandit algorithms dynamically shift traffic to the best-performing variant.

interface Variant {
  id: string;
  conversions: number;
  impressions: number;
}

// Thompson Sampling: choose variant with probability proportional to posterior
function selectVariant(variants: Variant[]): string {
  const samples = variants.map(v => {
    // Beta distribution sample approximation
    const alpha = v.conversions + 1;
    const beta = v.impressions - v.conversions + 1;
    return { id: v.id, sample: sampleBeta(alpha, beta) };
  });
  return samples.reduce((best, curr) => curr.sample > best.sample ? curr : best).id;
}

function sampleBeta(alpha: number, beta: number): number {
  // Approximation using gamma samples
  const x = gammaSample(alpha);
  const y = gammaSample(beta);
  return x / (x + y);
}

function gammaSample(shape: number): number {
  // Marsaglia and Tsang method (simplified)
  return -Math.log(Math.random()) * shape;
}

Micro-Conversion Optimization

Track small intent signals (demo views, chat interactions, scroll depth) as leading indicators before the primary conversion.

type MicroConversionEvent =
  | { type: 'demo_watched'; durationMs: number }
  | { type: 'chat_opened'; source: string }
  | { type: 'pricing_scrolled'; reachedBottom: boolean }
  | { type: 'feature_hovered'; featureId: string };

function trackMicroConversion(event: MicroConversionEvent): void {
  // Score each micro-conversion by predicted downstream value
  const scores: Record<MicroConversionEvent['type'], number> = {
    demo_watched: 10,
    chat_opened: 7,
    pricing_scrolled: 5,
    feature_hovered: 2,
  };

  const score = scores[event.type];
  const currentScore = Number(sessionStorage.getItem('intent_score') ?? '0');
  sessionStorage.setItem('intent_score', String(currentScore + score));

  // Trigger high-intent CTAs when score crosses threshold
  if (currentScore + score >= 20) {
    showHighIntentCTA();
  }

  navigator.sendBeacon('/analytics', JSON.stringify({ ...event, score }));
}

function showHighIntentCTA(): void {
  document.getElementById('sticky-cta')?.classList.remove('hidden');
}

---

## Supporting file: reference/geo-optimization.md

# GEO (Generative Engine Optimization) — 2026 Field Guide

## What changed in 2025–2026

- **AI Overviews scaled globally.** As of May 2025, AI Overviews are available in 200+ countries and 40+ languages [Source: Google, *AI Overviews expansion* (2025-05), https://blog.google/products/search/ai-overview-expansion-may-2025-update/]. AI Overviews appear on ~13% of all Google queries (Semrush AIO prevalence study peaked at ~25% in mid-2025, settled around 15.69% Nov 2025) [Source: Search Engine Land, https://searchengineland.com/google-ai-overviews-ctr-recovery-study-475566].
- **AI Mode is the new conversational layer.** Google AI Mode (launched at I/O 2025) reached US, India, Japan, South Korea, Indonesia, Brazil in 2025 and went near-global (~200 countries, 98 languages) at I/O 2026 (2026-05) with **Gemini 3.7 Flash (High)** as the default model [Source: Google blog — *AI Mode expands languages and locations* (2026-05), https://blog.google/products-and-platforms/products/search/ai-mode-expands-languages-locations/]. The classic SERP and AI Mode are merging into one continuous experience.
- **CTR impact is severe but cited pages benefit.** Seer Interactive (Sept 2025): organic CTR on AIO-present queries dropped **61% (1.76% → 0.61%)**, paid CTR dropped 68%; but **cited pages earn 35% more organic clicks (91% more paid)** than uncited pages on the same SERP [Source: Search Engine Land, https://searchengineland.com/google-ai-overviews-hurt-click-through-rates-454428]. CTR is also recovering: from 1.3% (Dec 2025) to 2.4% (Feb 2026), an 85% rebound [Source: https://searchengineland.com/google-ai-overviews-ctr-recovery-study-475566].
- **Citation decoupled from rank.** In mid-2025 ~76% of AI Overview citations came from the organic top-10; by early 2026 that share collapsed to 38% (some reports as low as 16%) — being ranked #1 no longer guarantees AI citation [Source: Edward Rippen — *AI Overviews citation strategy 2026*, https://edwardrippen.com/ai-overviews-citation-strategy-2026/]. Reddit and other community sources are increasingly cited (Tinuiti AI Citations Trends Q1 2026: social media share of AI citations >9%, Reddit dominant) [Source: CMSWire, https://www.cmswire.com/digital-marketing/reddits-rise-in-ai-citations-what-marketers-must-know-about-aeo-strategy/].

## The Princeton GEO framework

The term GEO and the original methodology come from Aggarwal, Murahari, Rajpurohit, Kalyan, Narasimhan, Deshpande, *GEO: Generative Engine Optimization* (Princeton / GA Tech / AI2 / IIT Delhi), ACM SIGKDD 2024 (preprint Nov 2023, arXiv:2311.09735). The paper tested nine optimization strategies across 10,000 queries and multiple generative engines; the winning combination — **adding statistics, citing sources, adding quotations, mentioning authorities** — raised visibility by **up to 40%** in AI-generated responses [Source: Princeton — *GEO: Generative Engine Optimization*, https://collaborate.princeton.edu/en/publications/geo-generative-engine-optimization/].

## Four-signal framework

| Signal | Question | Tactics |
|--------|----------|---------|
| Retrievability | Can AI bots fetch the page? | robots.txt allows search/retrieval bots; SSR or static prerender of primary content; no JS-only gating |
| Extractability | Can AI parse a structured answer? | Direct-answer first 200 words; 120–180 words per H2; FAQ + HowTo + Article + ItemList stacked schema |
| Credibility | Are claims defensible? | 3–5 inline citations from authoritative sources per page; original data / statistics; author bio with credentials |
| Entity clarity | Are entities disambiguated? | Schema.org `@id` cross-references; consistent canonical naming; Organization + WebSite + sameAs links |

## AI crawler taxonomy (2026-05)

> **Training-bot blocks do not affect AI search citation. Search/retrieval-bot blocks remove you from AI search entirely.** Audit both before changing robots.txt.

| Vendor | Training crawler (safe to block) | Search/retrieval bot (KEEP ALLOWED for citation) | User-initiated fetch |
|--------|----------------------------------|--------------------------------------------------|----------------------|
| OpenAI | `GPTBot` | `OAI-SearchBot` | `ChatGPT-User` |
| Anthropic | `ClaudeBot` | `Claude-SearchBot` | `Claude-User` (+ `claude-code` for CLI) |
| Google | `Google-Extended` | (Googlebot covers AIO/AI Mode) | `Google-NotebookLM`, `Google-Read-Aloud` |
| Perplexity | (none separate) | `PerplexityBot` | `Perplexity-User` |
| Apple | `Applebot-Extended` | `Applebot` | — |
| Meta | — | `meta-externalagent` | — |

Anthropic confirmed the 4-bot split (`ClaudeBot` / `Claude-SearchBot` / `Claude-User` / `claude-code`) in its public bot directory; SE Ranking observed that 73% of sites have unintentional barriers (broad robots.txt, CDN/WAF rules, JS-only rendering) blocking AI retrieval bots [Source: ALM Corp — *Anthropic's three-bot framework*, https://almcorp.com/blog/anthropic-claude-bots-robots-txt-strategy/].

### llms.txt status (2026-05): **do not rely on it**

SE Ranking study of 300,000 domains: **~10.13% adoption**, but **GPTBot, ClaudeBot, OAI-SearchBot, Claude-SearchBot, PerplexityBot, Google-Extended overwhelmingly do not fetch `/llms.txt`** and crawl HTML directly. As of Q1 2026, no major AI vendor has publicly committed to honoring llms.txt in production [Source: AEO Press — *State of llms.txt 2026*, https://www.aeo.press/ai/the-state-of-llms-txt-in-2026]. Use robots.txt + structured data + canonical content — not llms.txt — as the primary GEO control surface.

## GEO KPIs (replace traditional rank tracking)

| KPI | Definition | Benchmark |
|-----|------------|-----------|
| Mention Rate | % of AI answers in a tracked prompt set that name your brand | <5% invisible, 5–15% emerging, 15–30% strong, >30% category leader |
| Citation Rate | % of those answers that include a clickable link to your domain | Perplexity highest citation/mention ratio; Google AI Mode lowest |
| Share of Voice | Brand mentions vs each tracked competitor across the prompt set | Track per-prompt-cluster to detect topical weakness |

Tools: ConvertMate, Profound, Otterly, AthenaHQ, Goodie, Peec.

## Anti-patterns

- Treating GEO as a single-platform game (ChatGPT-only) — each engine has different source sets and retrieval mechanics.
- Blocking `OAI-SearchBot` / `Claude-SearchBot` / `PerplexityBot` while keeping `Googlebot` allowed — you remain visible on Google AIO but invisible on ChatGPT, Claude, Perplexity citations.
- Publishing schema that contradicts visible page content — AI engines verify and penalize mismatches.
- Optimizing only for citation count, ignoring Share of Voice — high mentions with low citation links yield low downstream traffic.
- Ignoring Reddit and community surfaces — by 2026, community-sourced AI citations exceed 9% and are growing.

## References

- Aggarwal et al., *GEO: Generative Engine Optimization* (SIGKDD 2024 / arXiv:2311.09735).
- Google, *AI Mode expands languages and locations* (2026-05), https://blog.google/products-and-platforms/products/search/ai-mode-expands-languages-locations/
- Seer Interactive AI Overviews CTR studies (Sept 2025 + Feb 2026).
- Ahrefs, *Update: AI Overviews Reduce Clicks by 58%* (Dec 2025), https://ahrefs.com/blog/ai-overviews-reduce-clicks-update/
- AEO Press, *State of llms.txt 2026*, https://www.aeo.press/ai/the-state-of-llms-txt-in-2026
- Tinuiti, *AI Citations Trends Report Q1 2026* (via CMSWire).
- ALM Corp, *Anthropic's Three-Bot Framework* (2026), https://almcorp.com/blog/anthropic-claude-bots-robots-txt-strategy/
- Schema.org v30.0 release (2026-03-19), https://schema.org/docs/releases.html

---

## Supporting file: reference/json-ld-templates.md

# JSON-LD Structured Data Templates

Schema.org JSON-LD templates for rich snippets in search results **and AI citation (AI Overviews / ChatGPT / Perplexity / Claude / Copilot)**.

> **2026 status:**
> - **Schema.org v30.0** released 2026-03-19 — 823 distinct types. New properties expanded for professional credentials, e-commerce, and digital supply-chain transparency, optimized for AI verification. [Source: https://schema.org/docs/releases.html]
> - **FAQ rich results retired** in Google blue-link SERPs (Jun 2026 — Rich Results Test support removed; Aug 2026 — Search Console API removed). HowTo rich results were already retired in 2023. **FAQPage and HowTo schema remain valid Schema.org types and are still parsed by AI engines** for citation — keep them. [Source: Search Engine Land, https://searchengineland.com/google-to-no-longer-support-faq-rich-results-476957]
> - **Use the most specific subtype**: `BlogPosting` ⊂ `Article`, `NewsArticle` ⊂ `Article`, `LocalBusiness` ⊂ `Organization`, `OnlineStore` ⊂ `LocalBusiness`. Specificity strengthens AI citation signals.
> - **Triple-stack (`Article` + `ItemList` + `FAQPage`)** in a single `@graph` array yields the strongest AI citation lift in the Princeton GEO methodology.

## Product

```html
<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "Product",
  "name": "Product Name",
  "image": [
    "https://example.com/photos/1x1/photo.jpg",
    "https://example.com/photos/4x3/photo.jpg"
  ],
  "description": "Product description here",
  "sku": "SKU-12345",
  "brand": {
    "@type": "Brand",
    "name": "Brand Name"
  },
  "offers": {
    "@type": "Offer",
    "url": "https://example.com/product",
    "priceCurrency": "JPY",
    "price": "9800",
    "priceValidUntil": "2025-12-31",
    "availability": "https://schema.org/InStock",
    "seller": {
      "@type": "Organization",
      "name": "Seller Name"
    }
  },
  "aggregateRating": {
    "@type": "AggregateRating",
    "ratingValue": "4.5",
    "reviewCount": "123"
  }
}
</script>

Article / Blog Post (prefer BlogPosting for blog content)

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "BlogPosting",
  "headline": "Article Title (max 110 characters)",
  "image": [
    "https://example.com/photos/1x1/photo.jpg"
  ],
  "datePublished": "2026-01-15T08:00:00+09:00",
  "dateModified": "2026-05-20T10:00:00+09:00",
  "author": {
    "@type": "Person",
    "name": "Author Name",
    "url": "https://example.com/author",
    "jobTitle": "Senior Engineer",
    "hasCredential": {
      "@type": "EducationalOccupationalCredential",
      "credentialCategory": "certification",
      "name": "AWS Solutions Architect Professional"
    }
  },
  "publisher": {
    "@type": "Organization",
    "name": "Publisher Name",
    "logo": {
      "@type": "ImageObject",
      "url": "https://example.com/logo.png"
    }
  },
  "description": "Article description for search results"
}
</script>

author.hasCredential / jobTitle strengthen E-E-A-T signals — important after the Google March 2026 Core Update which weights author credential evidence more heavily on YMYL content (73% of top YMYL pages now show detailed author credentials vs 58% pre-update).

FAQ

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "FAQPage",
  "mainEntity": [
    {
      "@type": "Question",
      "name": "What is your return policy?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "You can return any item within 30 days of purchase."
      }
    },
    {
      "@type": "Question",
      "name": "How long does shipping take?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Standard shipping takes 3-5 business days."
      }
    }
  ]
}
</script>

Breadcrumb

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "BreadcrumbList",
  "itemListElement": [
    {
      "@type": "ListItem",
      "position": 1,
      "name": "Home",
      "item": "https://example.com/"
    },
    {
      "@type": "ListItem",
      "position": 2,
      "name": "Category",
      "item": "https://example.com/category"
    },
    {
      "@type": "ListItem",
      "position": 3,
      "name": "Current Page",
      "item": "https://example.com/category/page"
    }
  ]
}
</script>

Organization

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "Organization",
  "name": "Company Name",
  "url": "https://example.com",
  "logo": "https://example.com/logo.png",
  "sameAs": [
    "https://twitter.com/company",
    "https://www.linkedin.com/company/company",
    "https://github.com/company"
  ],
  "contactPoint": {
    "@type": "ContactPoint",
    "telephone": "+81-3-1234-5678",
    "contactType": "customer service",
    "availableLanguage": ["Japanese", "English"]
  }
}
</script>

LocalBusiness

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "LocalBusiness",
  "name": "Business Name",
  "image": "https://example.com/photo.jpg",
  "address": {
    "@type": "PostalAddress",
    "streetAddress": "1-2-3 Shibuya",
    "addressLocality": "Shibuya-ku",
    "addressRegion": "Tokyo",
    "postalCode": "150-0001",
    "addressCountry": "JP"
  },
  "geo": {
    "@type": "GeoCoordinates",
    "latitude": 35.6595,
    "longitude": 139.7004
  },
  "telephone": "+81-3-1234-5678",
  "openingHoursSpecification": [
    {
      "@type": "OpeningHoursSpecification",
      "dayOfWeek": ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"],
      "opens": "09:00",
      "closes": "18:00"
    }
  ]
}
</script>

SoftwareApplication

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "SoftwareApplication",
  "name": "App Name",
  "operatingSystem": "Web, iOS, Android",
  "applicationCategory": "ProductivityApplication",
  "offers": {
    "@type": "Offer",
    "price": "0",
    "priceCurrency": "USD"
  },
  "aggregateRating": {
    "@type": "AggregateRating",
    "ratingValue": "4.8",
    "ratingCount": "1000"
  }
}
</script>

Supporting file: reference/keyword-research.md

Keyword Research Methodology

Purpose

Build the keyword universe that drives both traditional SEO ranking and GEO (AI-search) citation. Without intent classification and clustering, content competes on the wrong queries and scatters topical authority.

Scope Boundary

  • IN scope: seed expansion, search-intent classification, query clustering, SERP feature analysis, AI-prompt mining, prioritization scoring.
  • OUT of scope: on-page meta implementation (seo), JSON-LD authoring (geo), conversion experiments (cro), competitor positioning (delegate to compete), KPI tracking dashboards (delegate to pulse).

Core Concepts

Four Search Intents (Google's Quality Rater Guidelines)

IntentPatternExample QueryGoal
Informational"what / how / why""what is RAG"Answer / explain
Navigationalbrand or product name"anthropic claude"Find a specific destination
Commercial"best / vs / review""best LLM API for production"Evaluate alternatives
Transactional"buy / pricing / signup""claude api pricing"Take action

Misclassification is the most common keyword-research failure: writing a buying-guide article for an informational query loses both rank and citation.

Modifiers That Reveal Intent

ModifierLikely Intent
how to, what, why, explain, tutorial, guide, definitionInformational
login, signin, dashboard, [brand] + [feature]Navigational
best, top, vs, comparison, review, alternatives, "X or Y"Commercial
buy, price, pricing, cheap, discount, signup, free trialTransactional
near me, [city], [country]Local / geographic

Long-Tail Distribution

Roughly 70% of all search queries are long-tail (3+ words, low individual volume). Long-tail traffic converts at 2.5–4× head-term rates and is significantly easier to rank for. A keyword universe weighted entirely toward head terms is a competition trap.

TierWord CountVolumeCompetitionConversion
Head1–2HighVery HighLow
Mid-tail2–4MediumHighMedium
Long-tail4–8Low–MediumLow–MediumHigh

SERP Feature Signals

The SERP for a query tells you what content format the engine prefers:

SERP FeatureImplication
Featured snippetDirect-answer paragraph (40–60 words) wins
People Also AskFAQ schema + Q&A subheadings work
Video carouselEmbed video; pure text underranks
Image packOriginal images required
Product carouselProduct schema + price/rating
AI OverviewGEO optimization mandatory; structured data + first-200-word answer
Knowledge panelEntity is well-defined; build around the canonical entity
Map packLocal intent; LocalBusiness schema

Always inspect the live SERP before committing — assumptions about format are wrong ~30% of the time.

Keyword Difficulty Heuristics (Without Paid Tools)

Free signals you can read manually:

  1. Domain Rating of top 10 — if half are DR 80+, head-term ranking is a multi-quarter project.
  2. Forum / Reddit / community in top 10 — gap, easier to rank with a quality canonical answer.
  3. AI Overview present — citation is the primary win, not rank #1.
  4. Search volume < 100/mo — long-tail; rank fast but small individual yield.
  5. Wikipedia + .gov + .edu in top 10 — entity-level query, content needs deep authority.
  6. All top results > 2 years old — refresh / update opportunity.

Query Clustering

Group queries that share a SERP. Method (manual or automated):

  1. Pull the top 10 results for each query.
  2. If queries A and B share ≥ 4 of the top 10 URLs, they are the same SERP cluster.
  3. One cluster = one canonical content asset; do not create cannibalizing pages.
  4. Re-cluster every 90 days — Google reshuffles intent boundaries quarterly.

Tools that automate this: Keyword Insights, Surfer SEO, Ahrefs Parent Topic, Semrush Keyword Strategy Builder. Fully manual is feasible for clusters under 100 queries.

AI-Prompt Mining (GEO)

Traditional keyword research targets typed search; GEO research targets the prompts that bring AI engines to your domain. Sources:

SourceWhat to Extract
ChatGPT / Claude / Gemini / Perplexity prompt logsPhrase patterns ("Compare X to Y for [persona]")
Reddit + Discord + Slack archivesReal natural-language formulations
Customer support chat / sales call transcriptsBuying-stage prompts
Google "People Also Ask" + autocompletePrompt seeds
Quora / Stack OverflowLong-form question patterns

AI prompts are typically 12–40 words, much longer than typed search. Capture the verbatim phrasing, not a normalized form.

Prioritization Scoring (RICE-style)

FactorWeightNotes
Reachvolume × CTR-by-rank-target2026 reality (AIO-present queries): Seer Sept 2025 measured organic CTR collapse from 1.76% to 0.61% (-61%) on AIO queries; rebounded to 2.4% by Feb 2026. For non-AIO queries use ~30% CTR for #1, 15% for #2, 10% for #3. For AIO queries, separately model Citation Rate because being cited drives +35% organic clicks. [Source: Search Engine Land, https://searchengineland.com/google-ai-overviews-ctr-recovery-study-475566]
Impact$ value per visitor × intent multiplierTransactional 5×, Commercial 3×, Informational 1×
Confidence0.4 / 0.7 / 0.9 by difficultyDR mismatch reduces; topical authority match increases
Effortcontent + linking + technical, in person-daysConservative estimate

Score = (Reach × Impact × Confidence) / Effort. Sort descending. Cap your roadmap at the top 30; below that the variance dominates the signal.

Workflow

  1. Seed harvesting — collect 20–50 seeds from product pages, sales transcripts, support tickets, competitors, autocomplete.
  2. Expansion — for each seed, pull modifier expansions (how/best/vs/buy + question words).
  3. Volume + difficulty enrichment — annotate each candidate with monthly volume and a difficulty proxy.
  4. Intent classification — tag every candidate with one of the four intents.
  5. SERP inspection — for the top 100 candidates, check the live SERP feature mix and snapshot it.
  6. Clustering — group by SERP overlap (≥ 4 shared URLs in top 10).
  7. AI-prompt mining — collect 20–50 verbatim AI prompts that map to the same clusters.
  8. Prioritization — score with RICE; cut to a 30-item roadmap.
  9. Brief generation — for each top cluster, write a content brief: target query, intent, SERP features to win, AI prompts to address, recommended schema, word count target.

Output Template

keyword_universe:
  seeds: [seed_1, seed_2, ...]
  candidates_total: 4327
  after_dedup: 1850
  classification:
    informational: 920
    commercial: 540
    transactional: 240
    navigational: 150
  clusters:
    - id: C-01
      canonical_query: "rag retrieval design patterns"
      sibling_queries: [...]
      intent: informational
      monthly_volume: 4200
      difficulty: medium
      serp_features: [featured_snippet, paa, ai_overview]
      ai_prompts:
        - "What are the key tradeoffs between dense and sparse retrieval for RAG?"
        - "Compare BM25 vs hybrid search for production RAG systems."
      rice_score: 184
      recommended_brief:
        format: long-form guide + FAQ
        word_count_target: 2200
        schema: [Article, FAQPage, BreadcrumbList]
        first_200_words_must_answer: "What are RAG retrieval design patterns?"
  roadmap_top_30: [C-01, C-04, C-07, ...]

Anti-Patterns

  • Targeting head terms with low domain authority — burning months on queries you cannot rank for.
  • Skipping intent classification — content format mismatch is the #1 underperformance cause.
  • One page per query instead of one page per cluster — cannibalization splits authority.
  • Optimizing for volume alone, ignoring intent multiplier — high-traffic, low-revenue pages.
  • Using keyword tools' static "difficulty" score without inspecting the live SERP — tool scores lag SERP changes by 30–60 days.
  • Ignoring AI prompts — by 2026, AI search is 30%+ of all query traffic for many B2B verticals; prompts that don't appear in keyword tools never enter the roadmap.
  • Refreshing the universe annually instead of quarterly — intent drift makes 6-month-old clusters unreliable.
  • Treating navigational queries as content opportunities — you cannot win [Brand X] queries from outside Brand X's site.

Deliverable Contract

A keyword research deliverable is complete when:

  • ≥ 1,000 deduplicated candidates from seed expansion.
  • 100% intent-classified.
  • Top-100 candidates have live SERP snapshots within the last 30 days.
  • Clusters use SERP-overlap method (≥ 4 shared URLs).
  • AI prompts captured for each top cluster.
  • RICE scoring applied; top-30 roadmap selected.
  • Brief generated for each top-30 cluster (intent, format, schema, AI prompts, word target).
  • Refresh cadence documented (90 days default).

References

  • Google Search Quality Rater Guidelines (2024 update) — official intent definitions.
  • Andrei Broder, "A Taxonomy of Web Search" (2002) — original informational/navigational/transactional model.
  • Ahrefs, AI Overviews Reduce Clicks by 58% (2025-12), https://ahrefs.com/blog/ai-overviews-reduce-clicks-update/
  • Aleyda Solis, SEO Roadmap Methodology.
  • Aggarwal et al., GEO: Generative Engine Optimization (SIGKDD 2024 / arXiv:2311.09735) — citation patterns vs traditional queries.
  • Seer Interactive AIO CTR studies (Sept 2025, Feb 2026 update) — post-AI-Overview CTR curves.
  • Semrush AIO prevalence study 2025 — appears in ~13% of queries (Nov 2025: 15.69%).
  • Tinuiti, AI Citations Trends Q1 2026 — Reddit as growing AI-cited source post-Google×Reddit deal (2024-02).

Supporting file: reference/ogp-social-templates.md

OGP & Social Sharing Templates

2026 platform notes:

  • X (Twitter) still supports summary and summary_large_image cards; preferred image is 1200×675 (1.91:1, ≤5MB). Twitter's official Card Validator at cards-dev.twitter.com has been deprecated since 2022 — verify cards by posting from a private/scheduled draft instead. [Source: og-image.org / moda.app Twitter card 2026 guides]
  • Bluesky parses standard og:title / og:description / og:image (no custom AT-Protocol record needed) and renders them similar to X's summary_large_image layout. There is an open social-app issue (#5012) tracking a future small/summary card variant. [Source: github.com/bluesky-social/social-app/issues/5012]
  • LinkedIn / Facebook / Slack / Discord continue to consume standard OGP; LinkedIn now uses 1200×627 as the canonical share image dimension.

Open Graph (Facebook/LinkedIn)

<meta property="og:title" content="Page Title" />
<meta property="og:description" content="Description" />
<meta property="og:image" content="https://example.com/image.jpg" />
<meta property="og:url" content="https://example.com/page" />
<meta property="og:type" content="website" />
<meta property="og:site_name" content="Site Name" />

Image requirements: 1200x630px, < 8MB

Twitter Cards

<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content="Page Title" />
<meta name="twitter:description" content="Description" />
<meta name="twitter:image" content="https://example.com/image.jpg" />

Next.js Metadata API

export const metadata: Metadata = {
  title: 'Page Title',
  description: 'Description',
  openGraph: {
    title: 'Page Title',
    description: 'Description',
    images: [{ url: '/og-image.jpg', width: 1200, height: 630 }],
  },
  twitter: { card: 'summary_large_image' },
};

Supporting file: reference/ogp-twitter-card-guide.md

OGP / Twitter Card Implementation Guide

Complete templates for Open Graph Protocol and Twitter Card meta tags.

Basic Meta Tags (HTML)

<head>
  
  <title>Page Title - Site Name</title>
  <meta name="title" content="Page Title - Site Name">
  <meta name="description" content="Compelling description under 160 characters">

  
  <meta property="og:type" content="website">
  <meta property="og:url" content="https://example.com/page">
  <meta property="og:title" content="Page Title">
  <meta property="og:description" content="Compelling description for social sharing">
  <meta property="og:image" content="https://example.com/og-image.png">
  <meta property="og:image:width" content="1200">
  <meta property="og:image:height" content="630">
  <meta property="og:site_name" content="Site Name">
  <meta property="og:locale" content="ja_JP">

  
  <meta property="twitter:card" content="summary_large_image">
  <meta property="twitter:url" content="https://example.com/page">
  <meta property="twitter:title" content="Page Title">
  <meta property="twitter:description" content="Compelling description for Twitter">
  <meta property="twitter:image" content="https://example.com/twitter-image.png">
  <meta property="twitter:site" content="@username">
  <meta property="twitter:creator" content="@author">
</head>

Next.js Metadata API (App Router)

// app/page.tsx or app/layout.tsx
import type { Metadata } from 'next';

export const metadata: Metadata = {
  title: 'Page Title',
  description: 'Page description for search engines',
  openGraph: {
    title: 'OG Title',
    description: 'OG Description',
    url: 'https://example.com/page',
    siteName: 'Site Name',
    images: [
      {
        url: 'https://example.com/og-image.png',
        width: 1200,
        height: 630,
        alt: 'OG Image Alt',
      },
    ],
    locale: 'ja_JP',
    type: 'website',
  },
  twitter: {
    card: 'summary_large_image',
    title: 'Twitter Title',
    description: 'Twitter Description',
    site: '@username',
    creator: '@author',
    images: ['https://example.com/twitter-image.png'],
  },
};

Dynamic OG Image (Next.js)

// app/api/og/route.tsx
import { ImageResponse } from 'next/og';

export const runtime = 'edge';

export async function GET(request: Request) {
  const { searchParams } = new URL(request.url);
  const title = searchParams.get('title') ?? 'Default Title';

  return new ImageResponse(
    (
      <div
        style={{
          height: '100%',
          width: '100%',
          display: 'flex',
          flexDirection: 'column',
          alignItems: 'center',
          justifyContent: 'center',
          backgroundColor: '#1a1a2e',
          fontSize: 48,
          fontWeight: 'bold',
          color: 'white',
        }}
      >
        <div style={{ marginBottom: 24 }}>🚀</div>
        <div style={{ textAlign: 'center', padding: '0 48px' }}>{title}</div>
      </div>
    ),
    {
      width: 1200,
      height: 630,
    }
  );
}

// Usage in page metadata
export async function generateMetadata({ params }): Promise<Metadata> {
  const title = await getPageTitle(params.slug);
  return {
    openGraph: {
      images: [`/api/og?title=${encodeURIComponent(title)}`],
    },
  };
}

React Helmet Component

import { Helmet } from 'react-helmet-async';

interface SEOProps {
  title: string;
  description: string;
  image?: string;
  url?: string;
  type?: 'website' | 'article';
}

export function SEO({ title, description, image, url, type = 'website' }: SEOProps) {
  const siteUrl = 'https://example.com';
  const defaultImage = `${siteUrl}/default-og.png`;

  return (
    <Helmet>
      <title>{title}</title>
      <meta name="description" content={description} />

      {/* Open Graph */}
      <meta property="og:type" content={type} />
      <meta property="og:title" content={title} />
      <meta property="og:description" content={description} />
      <meta property="og:image" content={image || defaultImage} />
      <meta property="og:url" content={url || siteUrl} />

      {/* Twitter */}
      <meta name="twitter:card" content="summary_large_image" />
      <meta name="twitter:title" content={title} />
      <meta name="twitter:description" content={description} />
      <meta name="twitter:image" content={image || defaultImage} />
    </Helmet>
  );
}

OG Image Specifications (2026-05)

PlatformCard TypeDimensionsAspect RatioNotes
Facebookog:image1200 × 6301.91:1≤8MB
LinkedInog:image1200 × 6271.91:1LinkedIn caches aggressively — append ?v= query to force refresh
X (Twitter)summary_large_image1200 × 675 (preferred) or 1200 × 6281.91:1≤5MB; JPG/PNG/GIF/WEBP. cards-dev.twitter.com deprecated 2022
X (Twitter)summary144 × 144 (min)1:1Small thumbnail card
Blueskyog:image1200 × 6301.91:1Renders summary_large_image equivalent via standard OGP
Slack/Discordog:image1200 × 6301.91:1Discord truncates titles >256 chars
Mastodonog:image1200 × 6301.91:1Caches via fediverse relays — expect 24-48h propagation

Verification Tooling (2026)

ToolUse
Facebook Sharing Debugger (https://developers.facebook.com/tools/debug/)Facebook + LinkedIn fallback verification, force re-scrape
LinkedIn Post Inspector (https://www.linkedin.com/post-inspector/)LinkedIn-specific cache flush
X — post a scheduled/private tweetReplaces deprecated Card Validator
OpenGraph.xyz / opengraph.devCross-platform preview
Bluesky — paste URL in compose boxManual preview check

Supporting file: reference/retention/engagement-triggers.md

Growth Re-engagement Triggers

Purpose: Trigger design, cadence limits, and reusable message structure for re-engagement. Contents: trigger table, channel selection, delay rules, message examples.

Trigger Configuration

TriggerConditionChannelDelayMax frequency
dormant_3_days3 <= daysSinceLastVisit < 7Push0h4/month
dormant_7_days7 <= daysSinceLastVisit < 14Email12h2/month
incomplete_onboardingOnboarding incomplete and >= 1 day since signupEmail24h3/month
feature_discovery> 5 sessions and key feature unusedIn-app0h1/month
streak_at_riskActive streak and < 6h until expiryPush0h30/month

Channel Rules

  • Push: use for short-lived urgency, including early dormancy and streak protection.
  • Email: use for recovery, incomplete setup, and higher-context value reminders.
  • In-app: use for contextual feature discovery after a user has demonstrated core adoption.

Message Patterns

const templates = {
  miss_you_3_days: {
    title: 'We miss you',
    body: 'It has been 3 days since your last visit. Want to see what is new?',
    cta: 'Check it now'
  },
  win_back_7_days: {
    subject: '[Name], here is what changed',
    body: 'You have been away for a while. We shipped [feature] so you can now [benefit].',
    cta: 'See what is new'
  },
  complete_setup: {
    subject: 'You are almost done',
    body: 'Finish the remaining setup steps to unlock [benefit]. It should take about 5 minutes.',
    cta: 'Continue setup'
  },
  protect_streak: {
    title: 'Keep your streak alive',
    body: 'You are on a [N]-day streak. Use the product today to keep it going.',
    cta: 'Open the product'
  }
};

Supporting file: reference/retention/retention-analysis.md

Growth Retention Analysis Framework

Purpose: Cohort analysis, churn scoring, drop-off diagnosis, and retention reporting. Contents: cohort template, risk signal scoring, churn tiers, recommended actions, report template.

Cohort Retention Analysis Template

## Retention Analysis: [Product/Feature]

### Cohort Retention Table
| Cohort | Week 0 | Week 1 | Week 2 | Week 4 | Week 8 | Week 12 |
|--------|--------|--------|--------|--------|--------|---------|
| Jan W1 | 100% | 42% | 35% | 28% | 22% | 18% |
| Jan W2 | 100% | 45% | 38% | 30% | 24% | 20% |
| Feb W1 | 100% | 48% | 40% | 32% | - | - |

### Key Metrics
| Metric | Current | Target | Status |
|--------|---------|--------|--------|
| Day 1 Retention | [X%] | [Y%] | [Status] |
| Week 1 Retention | [X%] | [Y%] | [Status] |
| Month 1 Retention | [X%] | [Y%] | [Status] |
| Month 3 Retention | [X%] | [Y%] | [Status] |

### Drop-off Analysis
| Period | Drop-off % | Primary Reason | Intervention |
|--------|-----------|----------------|--------------|
| Day 0-1 | [X%] | [Reason] | [Action] |
| Day 1-7 | [X%] | [Reason] | [Action] |
| Week 1-4 | [X%] | [Reason] | [Action] |

### Retention Curve Shape
- Flattening point: Week [X]
- Target stable retention: [X%]

Churn Risk Scoring

SignalThresholdScore impactInterpretation
Inactivity> 14 days+30Severe dormancy
Inactivity> 7 days+15Early dormancy
Usage declinesessionsLast7Days < 50% of recent baseline+25Fast engagement drop
Feature adoptionfeatureUsageScore < 30+20Core value not adopted
Support issuessupportTicketsOpen > 2+15Unresolved friction
NPS<= 6+20Detractor risk
BillingbillingIssues = true+25Payment friction

Churn Levels And Default Actions

ScoreLevelDefault action
>= 70CriticalImmediate 1:1 follow-up
50-69HighPersonalized re-engagement
30-49MediumAutomated re-engagement campaign
< 30LowContinue normal engagement

Implementation Notes

  • Combine behavior, satisfaction, and billing signals; do not rely on a single flag.
  • Use the scoring table as a prioritization tool, not as a replacement for segment context.
  • Escalate faster when inactivity and unresolved support issues appear together.

Report Template

## Retention Analysis: [Product/Feature]

### Cohort Retention Table
| Cohort | Week 0 | Week 1 | Week 2 | Week 4 | Week 8 | Week 12 |
|--------|--------|--------|--------|--------|--------|---------|
| [Cohort] | 100% | [X%] | [X%] | [X%] | [X%] | [X%] |

### Key Metrics
| Metric | Current | Target | Status |
|--------|---------|--------|--------|
| Day 1 Retention | [X%] | [Y%] | [Status] |
| Week 1 Retention | [X%] | [Y%] | [Status] |
| Month 1 Retention | [X%] | [Y%] | [Status] |
| Month 3 Retention | [X%] | [Y%] | [Status] |

### Drop-off Analysis
| Period | Drop-off % | Primary Reason | Intervention |
|--------|-----------|----------------|--------------|
| [Period] | [X%] | [Reason] | [Action] |

### Churn Risk Priorities
| Segment | Score | Level | Top Signals | Action |
|---------|-------|-------|-------------|--------|
| [Segment] | [X] | [Level] | [Signals] | [Action] |

Supporting file: reference/retention/winback-campaign.md

Win-Back Campaign Reference

Purpose: Recover cancelled or long-dormant users with a recency-weighted offer sequence, multi-touch cadence, and a reactivation metric tied to Pulse. Distinguishes voluntary from involuntary cancels.

Scope Boundary

  • growth winback: Cancelled / long-dormant user recovery (this document).
  • growth reengagement (elsewhere): Still-active dormant user re-activation. Default. Winback is a deeper recovery path.
  • growth churn (elsewhere): Churn prevention before cancellation.
  • Growth (elsewhere): New-user acquisition campaigns. Winback is recovery, not acquisition.
  • Prose (elsewhere): Campaign copy (notification). Winback designs the plan; Prose writes the words.
  • gateway (elsewhere): Delivery infrastructure.
  • Pulse (elsewhere): Reactivation metric and funnel reporting.

Voluntary vs Involuntary Cancels

Involuntary (payment / card failure)  →  Route to dunning first
                                         Clean card issue, attempt re-charge
                                         Separate from winback flow

Voluntary (active choice to leave)    →  Winback candidate
                                         Segment by cancel reason
                                         Apply recency-weighted offer

Dunning handles involuntary. Winback handles voluntary only.

Recency Cohorts

CohortDays since cancel / dormantOffer strengthCadence
Fresh0-14 daysSoft (content, feature reminder)Light touch, 1-2 emails
Warm15-30 daysMedium (discount ≤20%, free month)3 emails + 1 push
Cool31-90 daysStrong (discount 30-50%, new feature hero)4-5 touches across channels
Cold91-180 daysHero (50%+ off or credits)Final push + quiet
Frozen>180 daysMinimal last attempt1 email, then stop

Rule: offer strength scales with recency inverse — stronger for colder. Acquisition-level economics apply to cold winback.

Segmentation Dimensions

For each recency cohort, further segment by:

  1. Cancel reason (if captured): price / features / unused / support / switched competitor.
  2. Plan tier at cancel: free / paid-base / paid-premium / enterprise.
  3. Lifetime value at cancel: LTV tier (top / mid / low).
  4. Engagement peak: power user vs. casual vs. never-activated.
  5. Primary use case: what feature they used most.
  6. Channel preference: email-only / push-allowed / SMS opted-in.

Never send the same message to all cohorts. A power user who left for price needs different copy than a never-activated user who left for lack of understanding.

Offer Design

Cancel reasonRecommended offer
Price / costDiscount (scaled to cohort), longer billing period, annual at monthly price
Missing features"We built it" announcement + early access if relevant
Didn't see value / underusedOnboarding reset + human help offer + success-story share
Support issueApology + credit + named CSM / concierge onboarding
Switched competitorMigration assistance + data import + differentiator highlight
Lifecycle (no longer needed)Pause option, archive, come-back-anytime landing
UnknownSoft touch, value reminder, low-friction return path

Avoid: bribes with no context, identical discount for everyone, discount that undercuts current paying users' price.

Multi-Touch Cadence Example (Warm cohort, price objection)

Day 0   (cancel)   : offboarding email confirming cancel, low-key "come back" link
Day 3   : value reminder email — top 3 features they used
Day 7   : offer — "30% off for 3 months, start where you left off"
Day 14  : feature-launch push (if relevant release since cancel)
Day 21  : final soft touch email — success story from similar user
Day 30  : stop cadence; move to Cool cohort if no return

Quiet period: 60 days before any further contact

Frequency cap: no more than 1 marketing touch / 3 days in winback.

Deliverability and Suppression

  • Global suppression: honored-opt-out list never gets winback.
  • Complaint list: spam-reporters never get winback.
  • Hard-bounce list: invalid addresses suppressed.
  • Winback fatigue suppression: user who's been through 2 full winback cycles without returning → 180-day cooldown.
  • Regulatory: CAN-SPAM (unsubscribe ≤ 10 business days), GDPR (legitimate interest balancing test), CASL Canada (consent required), Japan APPI.

Route compliance checks to Cloak/Canon[regulatory] for regulated regions.

Reactivation Metric

Reactivation Rate = returned_users / winback_recipients (per cohort, per campaign)

Benchmarks (typical SaaS):

  • Fresh cohort: 15-30%
  • Warm: 8-15%
  • Cool: 3-8%
  • Cold: 1-3%
  • Frozen: <1%

Downstream: track LTV of reactivated users vs original LTV. Sticky reactivation means reactivated LTV ≥ 60% of original. Lower than that suggests price-incentive-only returns who churn again.

Offer Cannibalization Check

Before shipping a winback offer, verify:

  • Current paying users cannot easily discover and exploit the winback discount.
  • Serial cancel-rejoin gaming is rate-limited (one winback offer per 365 days).
  • Offer does not undercut a more expensive plan and drive current users to downgrade.

Output Template

## Win-Back Campaign: [Name]

### Target Segment
- **Recency cohort**: [Fresh / Warm / Cool / Cold / Frozen]
- **Size**: [N users]
- **Primary cancel reason**: [price / features / etc.]
- **Secondary segmentation**: [plan tier, LTV tier, channel preference]

### Offer
- **Type**: [discount / extended trial / feature access / migration help / pause]
- **Strength**: [% or value]
- **Duration**: [days / months]
- **Justification**: matched to cancel reason and cohort economics

### Cadence
| Day | Channel | Content goal | CTA |
|-----|---------|--------------|-----|
| 0 | email | offboarding confirm | "we'll be here" |
| 3 | email | value reminder | "see what's new" |
| 7 | email | offer | "[offer CTA]" |
| ... | ... | ... | ... |

### Compliance
- [ ] Global suppression respected
- [ ] Hard-bounce / complaint lists applied
- [ ] Unsubscribe ≤ 10 business days
- [ ] Regional regulation verified (CAN-SPAM / GDPR / CASL / APPI)

### Metrics
- **Primary**: Reactivation rate (benchmark: [cohort-specific])
- **Secondary**: Reactivated-user 90-day retention, reactivated LTV vs original
- **Guardrail**: current-user cannibalization < 1%, unsubscribe rate < 2%

### Handoffs
- Prose `notification`: copy per touch
- gateway: email / push / SMS delivery
- Pulse: reactivation event + funnel
- Experiment: A/B test offer strength and copy
- Cloak / Canon[regulatory]: regulatory review
- Growth: ensure no overlap with active promos

Anti-Patterns

Anti-patternFix
Winback to users who reported spamHonor complaint list
Same discount for everyoneSegment by cancel reason
Aggressive SMS without opt-inEmail-only for non-opted cohorts
Winback discount leaks to active usersPlug the leak before campaign
No LTV analysis post-reactivationMeasure reactivated-LTV to avoid price-only returns
Forever-on winback cadenceHard stop at cohort end; 60-day quiet
Winback on dunning-side cancelFix dunning first

Deliverable Contract

When winback completes, emit:

  • Segment definition (recency cohort × reason × tier × LTV × channel).
  • Offer design matched to cohort and reason.
  • Cadence table (day × channel × content × CTA).
  • Compliance checklist (suppression, regulation, unsubscribe).
  • Metrics plan (reactivation rate, 90-day retention, LTV, guardrails).
  • Cannibalization check.
  • Handoffs: Prose, gateway, Pulse, Experiment, Cloak/Canon[regulatory], Growth.

References

  • Reforge — Winback Playbook
  • Andrew Chen — "The Cold-Start Problem" (cohort recovery)
  • Sean Ellis — Hacking Growth (winback loops)
  • CAN-SPAM / GDPR / CASL / APPI regulatory references
  • Customer.io, Braze, Iterable — winback automation patterns
  • SaaS Metrics Benchmarks (OpenView, KeyBanc) — reactivation rates by recency

Supporting file: reference/seo-audit.md

Full-Site SEO Audit

Purpose

Diagnose technical and structural issues that block traffic regardless of content quality. A page-level meta fix wastes effort if the site is uncrawlable, mis-indexed, or topologically incoherent. The audit produces a prioritized backlog, not a 200-row spreadsheet of findings.

2026 audit pressure points:

  • Google March 2026 Core Update rolled out 2026-03-27 alongside a paired Spam Update (fastest spam update ever, completed in <20 hours). Both target AI-generated content lacking human editorial oversight via an upgraded SpamBrain (analysts attribute Gemini 4.0 Semantic Filter signals). 73% of top YMYL pages now display detailed author credentials, up from 58% pre-update. Audits must include AI-content authorship and E-E-A-T credential coverage. [Source: Search Engine Land / PPC.land coverage of March 2026 update, https://ppc.land/googles-march-2026-spam-update-is-live-what-changed-and-why-it-matters/]
  • FAQ rich results retired (Jun 2026 — Rich Results Test support removed, Aug 2026 — Search Console API). FAQPage schema still parses for AI Overviews / ChatGPT / Perplexity citation. Audit existing FAQ markup for schema-content consistency, not rich-result eligibility. [Source: Search Engine Land, https://searchengineland.com/google-to-no-longer-support-faq-rich-results-476957]
  • Schema.org v30.0 released 2026-03-19 (823 types), expanded credential / e-commerce / supply-chain schema for AI verification. [Source: https://schema.org/docs/releases.html]

Scope Boundary

  • IN scope: crawlability, indexability, site architecture, internal linking, content gap, log-file analysis (Googlebot + AI bots), schema coverage, hreflang, canonical hygiene, redirect chains.
  • OUT of scope: per-page meta authoring (seo), CRO experiments (cro), Core Web Vitals deep-dive (vitals), keyword universe construction (keyword), GEO content quality (geo).

Core Concepts

The 5-Layer Audit Stack

Audit in this order. Lower layers gate upper layers; do not optimize content on a site Google cannot crawl.

LayerQuestionTools
L1 CrawlabilityCan bots fetch your URLs?robots.txt, server logs, Screaming Frog, Sitebulb
L2 IndexabilityDoes Google keep them in the index?GSC Coverage report, site: operator, URL Inspection
L3 ArchitectureHow do pages connect?Internal linking map, click depth, orphan analysis
L4 ContentDo your pages match intent?Content gap vs competitors, thin-content threshold, cannibalization
L5 Schema / GEOAre you machine-readable?Rich Results Test, Schema.org validator, AI bot access

L1 Crawlability Checks

CheckPass Criterion
robots.txt fetchable200 OK at /robots.txt
Sitemap reachableXML sitemap returns 200; URLs accessible
No accidental disallowDisallow: / not in production
AI bot policy explicitGPTBot / ClaudeBot / PerplexityBot / OAI-SearchBot / Claude-SearchBot rules documented
Crawl budget healthyGooglebot fetches > 80% of indexable URLs per 30 days
Render pathJS-rendered content reachable (test with curl + with rendering)
Redirect chainsAll chains ≤ 1 hop
Soft 404Empty / boilerplate pages return 404, not 200

Important AI-bot distinction: training bots (GPTBot, ClaudeBot, Google-Extended, Applebot-Extended) and search/retrieval bots (OAI-SearchBot, Claude-SearchBot, ChatGPT-User, Claude-User, PerplexityBot, Perplexity-User) require different policy decisions. Blocking training bots does not affect AI-search citation. Blocking search/retrieval bots removes you from AI-search results.

Anthropic publishes a four-bot taxonomy (confirmed 2026-05): ClaudeBot (training), Claude-SearchBot (search index/retrieval), Claude-User (user-initiated fetch from Claude.ai), claude-code (Claude Code CLI WebFetch). Control each independently. [Source: ALM Corp, https://almcorp.com/blog/anthropic-claude-bots-robots-txt-strategy/]

Do not rely on llms.txt: SE Ranking found ~10.13% adoption across 300k domains but GPTBot, ClaudeBot, OAI-SearchBot, Claude-SearchBot, PerplexityBot, Google-Extended overwhelmingly skip /llms.txt and crawl HTML directly. No major AI vendor has publicly committed to honoring llms.txt as of Q1 2026. [Source: AEO Press, https://www.aeo.press/ai/the-state-of-llms-txt-in-2026]

L2 Indexability Checks

CheckPass Criterion
Canonical tagsEach URL points to its preferred canonical; no self-canonical loops; no canonical to redirected URL
noindex auditnoindex only on pages that should be excluded
Duplicate contentNo paginated / parameterized URLs indexed; UTM-stripping canonical present
HTTPS onlyAll HTTP redirects 301 to HTTPS
Mobile + desktop parityMobile has same content + structured data
Hreflang consistencyBidirectional x-default + per-locale, no orphan locales
Indexed-but-not-linkedGSC reports zero "Crawled - currently not indexed" growth
Sitemap-vs-indexed delta< 10% of submitted URLs are unindexed

L3 Architecture Checks

CheckPass Criterion
Click depthAll commercially important pages reachable in ≤ 3 clicks from home
Orphan pagesZero pages with no internal incoming links
Internal linking densityHigh-priority pages have ≥ 10 internal links from diverse contexts
Anchor text varietyMoney pages have 5+ distinct natural-language anchors
Hub & spoke topologyCluster pillars link to all cluster children; children cross-link
BreadcrumbsPresent on all non-root pages with BreadcrumbList schema
Paginationrel=prev/next removed; canonical to view-all where appropriate
Faceted navigationParameterized URLs are crawl-controlled (robots, canonical, or noindex,follow)

L4 Content Checks

CheckPass Criterion
Thin contentNo indexed page under 300 words unless intentionally a hub
CannibalizationNo two indexed pages target the same primary query
Content freshnessDate stamps + actual content updates on time-sensitive pages
Topical authorityPillar + cluster topology covers ≥ 80% of cluster queries
Content gapTop 10 competitor SERPs identify ≥ 50 missing topics
E-E-A-T signalsAuthor bios, credentials, dates, sources on every YMYL page
Image alt text100% of content images have descriptive alt text (≤ 125 chars)

L5 Schema and GEO Checks

CheckPass Criterion
Schema coverageOrganization + WebSite + BreadcrumbList sitewide
Page-type schemaArticle / Product / LocalBusiness / FAQ / HowTo where applicable
Specific over genericBlogPosting > Article; LocalBusiness > Organization
Triple-stack on GEO pagesArticle + ItemList + FAQPage on key cite-target pages
Schema-content consistencyEvery JSON-LD claim is visible on the page
Validation100% pass on Google Rich Results Test
AI Overview eligibilityDirect-answer first 200 words; 120–180 words per H2 section
Inline citations3–5 authoritative sources cited per GEO-target article
AI bot access verifiedServer logs show OAI-SearchBot / Claude-SearchBot / PerplexityBot fetches

Log-File Analysis

Server logs are the only ground truth for crawler behavior. Look for:

PatternDiagnosis
Googlebot 4xx rate > 5%Broken links or aggressive blocking
Googlebot 5xx rate > 1%Server overload during crawl windows
Googlebot fetches dominated by low-value URLs (filters, search results)Crawl budget waste; tighten robots/canonical
AI bots in logs but zero AI citationsCrawl works, content fails — content / schema problem
AI bots not in logsBlocked by robots, CDN, WAF, or JS-only rendering
304 ratio for sitemap URLs > 90%Stale content; not bad but signals refresh opportunity

Tools: GoAccess, Splunk, Screaming Frog Log File Analyzer, Botify, Lumar.

Audit Output: The 30-Item Backlog

Resist the 200-row spreadsheet. Audits fail by overwhelming the implementer. Cap output at 30 prioritized items grouped by layer. Each item:

  • Title (one line)
  • Layer (L1–L5)
  • Severity (Blocker / High / Medium / Low)
  • Affected URL count
  • Effort estimate (S / M / L)
  • Recommended fix (concrete, not "improve X")
  • Verification step

Workflow

  1. Snapshot baseline — GSC export (last 90 days), site: count, top-100 page log-file extract.
  2. Run L1 — robots, sitemap, redirect chains, AI bot policy.
  3. Run L2 — canonical, noindex, hreflang, duplicate detection.
  4. Run L3 — crawl with Screaming Frog or Sitebulb; map click depth and orphans.
  5. Run L4 — content gap vs top-3 competitors per cluster; thin-content sweep.
  6. Run L5 — schema coverage, GEO direct-answer check, AI bot log access.
  7. Triage — group findings, drop noise, prioritize by traffic-at-risk × effort.
  8. Cap to 30 items — anything below threshold goes into a parking-lot file, not the active backlog.
  9. Hand off — to seo for per-page implementation, to vitals for performance items, to geo for AI-citation items, to bolt for performance code, to artisan for UI changes.

Output Template

audit_report:
  baseline:
    indexed_pages: 12480
    avg_click_depth: 3.7
    googlebot_fetches_30d: 184320
    ai_bots_in_logs: [GPTBot, ClaudeBot, PerplexityBot]
    ai_bots_missing: [OAI-SearchBot, Claude-SearchBot]  # CRITICAL
  layers:
    L1:
      passed: 6
      failed: 2
    L2:
      passed: 7
      failed: 1
    L3:
      passed: 5
      failed: 3
    L4:
      passed: 4
      failed: 3
    L5:
      passed: 4
      failed: 5
  backlog_top_30:
    - id: A-01
      layer: L5
      title: "OAI-SearchBot blocked by Cloudflare WAF rule #4421"
      severity: Blocker
      affected_urls: all
      effort: S
      fix: "Add Cloudflare rule to allow user-agent OAI-SearchBot/1.0 with rate limit 60/min"
      verify: "Confirm logs show 200 OK to OAI-SearchBot within 48h"
      handoff: scaffold | gear
    - id: A-02
      layer: L3
      title: "1,240 orphan blog posts (no internal links)"
      severity: High
      affected_urls: 1240
      effort: M
      fix: "Add 'Related posts' module powered by topical cluster ID; link 5 siblings per post"
      verify: "Re-crawl shows < 50 orphans"
      handoff: artisan
    # ... up to 30 items
  parking_lot_count: 87
  refresh_cadence: quarterly

Anti-Patterns

  • 200-row audit spreadsheets — rejected by implementers, nothing ships.
  • Auditing without log files — half of crawl issues are invisible from a desk crawler.
  • Ignoring AI search-bot vs training-bot distinction — silently blocks AI citation.
  • Trusting tool "site health score" as a single number — averages hide blockers.
  • Recommending fixes without effort estimates — implementer cannot triage.
  • Auditing on staging that disallows all bots — crawler-blocked staging gives false negatives.
  • "Improve X" findings without concrete fix steps — non-actionable.
  • Sitewide canonical-to-homepage — common bug; eliminates 99% of indexable pages.
  • Treating noindex + canonical to another URL as equivalent — they signal different things; mixing them confuses Google.
  • Auditing once per year — quarterly cadence is the minimum for SERP-relevant signals.

Deliverable Contract

A site audit is complete when:

  • All 5 layers checked with explicit pass/fail per check.
  • Log-file analysis covers ≥ 30 days for both Googlebot and AI bots.
  • Backlog capped at 30 items, prioritized.
  • Each item has severity, affected URL count, effort estimate, concrete fix, verification step, handoff agent.
  • Parking-lot file documents excluded findings (so nothing is lost).
  • Refresh cadence is set (quarterly default).

References

  • Google Search Central, Search Quality Evaluator Guidelines (2024).
  • Google Search Central, AI features and your website (2024) — AI bot taxonomy.
  • Aleyda Solis, Crawling Mondays (technical SEO methodology).
  • Bartosz Góralewicz, Onely — JS rendering and crawl auditing.
  • Botify, The Crawl Budget Optimization Playbook (2024).
  • Screaming Frog, SEO Vector User Guide.
  • Tomek Rudzki, Indexing Insight — indexability deep-dive.
  • John Mueller (Google), Search Off the Record podcast — canonical / hreflang clarifications.

Supporting file: reference/seo-checklist.md

SEO Implementation Checklist

Per-Page Requirements

  • Unique <title> (50-60 chars, keyword first)
  • Unique <meta name="description"> (150-160 chars)
  • Canonical URL: <link rel="canonical" href="...">
  • Single H1 tag with primary keyword
  • Heading hierarchy (H1 > H2 > H3, no skipping)
  • Image alt text (descriptive, not stuffed)
  • Internal links to related pages

Technical SEO

  • robots.txt configured
  • XML sitemap submitted
  • HTTPS everywhere
  • Mobile responsive
  • Core Web Vitals passing
  • No duplicate content
  • 301 redirects for moved pages

AI Overview / AI Mode Optimization

AI Overviews and AI Mode now sit at or near-global reach; citation inside an AI Overview earns significantly more clicks than an uncited result on the same SERP, and structured data + direct-answer formatting are table stakes. Full CTR figures, rollout timeline, and sources → reference/geo-optimization.md.

E-E-A-T Signals

  • Add author bios with credentials, publication dates, and update history
  • Link to primary sources and cite first-hand experience
  • Display qualifications, certifications, and organizational affiliations prominently

Answer-First Structure

  • Place a short, direct answer (2–3 sentences) at the top of the page before any preamble
  • Follow with supporting detail, evidence, and nuance below

Structured Data for AI Parsing

2026 update: FAQ rich results were retired from blue-link SERPs (Jun/Aug 2026); FAQPage and HowTo schema remain valid and are still parsed by AI engines for citation — keep them. Full detail and sources → reference/json-ld-templates.md.


<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "FAQPage",
  "mainEntity": [
    {
      "@type": "Question",
      "name": "What is the best way to improve Core Web Vitals?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Focus on LCP (image optimization, SSR), INP (reduce long tasks, use scheduler.yield), and CLS (reserve space for dynamic content)."
      }
    }
  ]
}
</script>


<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "HowTo",
  "name": "How to optimize LCP",
  "step": [
    { "@type": "HowToStep", "name": "Preload hero image", "text": "Add <link rel='preload'> for the LCP element." },
    { "@type": "HowToStep", "name": "Enable SSR", "text": "Use Next.js getStaticProps or generateStaticParams." }
  ]
}
</script>

Semantic HTML + Entity Optimization

  • Use <article>, <section>, <aside>, <nav> — avoid <div> for structural content
  • Mention entities (people, places, concepts) consistently with their canonical names
  • Build topic clusters: one pillar page + multiple supporting pages linked bidirectionally

Next.js 15 / React 19 SEO

Static Metadata

// app/blog/page.tsx — static metadata via export const
import type { Metadata } from 'next';

export const metadata: Metadata = {
  title: 'Blog | My Site',
  description: 'Latest articles on web performance and growth.',
  openGraph: {
    title: 'Blog | My Site',
    description: 'Latest articles on web performance and growth.',
    url: 'https://mysite.com/blog',
    siteName: 'My Site',
    images: [{ url: '/og/blog.png', width: 1200, height: 630 }],
    type: 'website',
  },
  twitter: {
    card: 'summary_large_image',
    title: 'Blog | My Site',
    description: 'Latest articles on web performance and growth.',
    images: ['/og/blog.png'],
  },
};

Dynamic Metadata

// app/blog/[slug]/page.tsx — dynamic metadata via generateMetadata
import type { Metadata } from 'next';

interface Props {
  params: Promise<{ slug: string }>;
}

// Only Server Components can export generateMetadata
export async function generateMetadata({ params }: Props): Promise<Metadata> {
  const { slug } = await params;
  // fetch is auto-memoized — same request won't be duplicated
  const post = await fetch(`/api/posts/${slug}`).then(r => r.json());

  return {
    title: `${post.title} | Blog`,
    description: post.excerpt,
    openGraph: {
      title: post.title,
      description: post.excerpt,
      images: [{ url: post.coverImage, width: 1200, height: 630 }],
      type: 'article',
      publishedTime: post.publishedAt,
      authors: [post.author.name],
    },
  };
}

export default async function BlogPostPage({ params }: Props) {
  const { slug } = await params;
  const post = await fetch(`/api/posts/${slug}`).then(r => r.json()); // memoized hit
  return <article>{/* ... */}</article>;
}

File-Based Metadata (App Router)

app/
  opengraph-image.jpg      → /og:image for all pages (fallback)
  blog/
    opengraph-image.jpg    → /blog og:image override
    [slug]/
      opengraph-image.tsx  → dynamic OG image via @vercel/og
  twitter-image.jpg
  robots.txt               → static robots rules
  sitemap.xml              → or sitemap.ts for dynamic generation

layout.tsx vs page.tsx Pattern

// app/layout.tsx — site-wide defaults
export const metadata: Metadata = {
  metadataBase: new URL('https://mysite.com'),
  title: { default: 'My Site', template: '%s | My Site' },
  description: 'Default site description.',
};

// app/blog/[slug]/page.tsx — per-page override (merges with layout)
export const metadata: Metadata = {
  title: 'Specific Post Title', // renders as "Specific Post Title | My Site"
};

Structured Data (JSON-LD)

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "Article",
  "headline": "Article Title",
  "author": { "@type": "Person", "name": "Author" },
  "datePublished": "2024-01-01"
}
</script>

How do I install Growth in Cursor, Claude Code, or Codex?

Run npx skills add simota/agent-skills --skill growth in the project where you want it, then ask your agent for the skill by name. The --skill flag installs only Growth, not every skill in the repository.

Where does Growth come from and what license is it under?

Growth comes from the simota/agent-skills repository on GitHub. That repository has 74 GitHub stars. The skill is published under the MIT license.

Prefer plain text? Read the Growth guide as markdown.