Written from 15 named sources Technical Requirements Document (TRD) Project: Edge-Rendered Share Route Optimization for AI Search and Social Discovery Author: Full-Stack Solutions Architect & GEO/AEO Specialist Status: Approved for Implementation Date: May 22, 2026 Executive Summary & Growth Flywheel Rationale The Pig Knuckle engineering team is transforming the /share/:token route from a blank page (to non-JS clients) into a fully machine-readable, AI-indexed, and social-unfurlable asset. Currently, Pig Knuckle operates as a pure Client-Side Rendered (CSR) React SPA hosted on Cloudflare Pages. When crawlers or social platforms request a shared artifact, they receive a bare index.html file with sitewide metadata. Because these crawlers do not execute JavaScript, they cannot read the dynamic content fetched by ShareView.tsx from Supabase. By implementing an Edge-Interceptor Pattern (Option 2) using a Cloudflare Worker, we intercept requests to /share/:token at the edge, fetch the artifact data server-side from our Supabase Edge Function, and inject semantic OpenGraph (OG), Twitter Card, and Schema.org JSON-LD tags directly into the HTML stream before it is delivered to the client. This approach preserves our lightweight, cost-effective CSR SPA architecture while enabling instant, server-side metadata delivery. ┌────────────────────────────────────────────────────────────────────────┐ │ THE GEO GROWTH FLYWHEEL │ ├────────────────────────────────────────────────────────────────────────┤ │ │ │ ┌─────────────────────────┐ ┌─────────────────────────────┐ │ │ │ Rich Semantic Markup │───────>│ Cited by AI Search Engines │ │ │ │ (JSON-LD & Microdata) │ │ (Perplexity, SearchGPT) │ │ │ └─────────────────────────┘ └─────────────────────────────┘ │ │ ▲ │ │ │ │ ▼ │ │ ┌─────────────────────────┐ ┌─────────────────────────────┐ │ │ │ Googlebot AI Overviews │ │ High-Intent Referral │ │ │ │ Surfaces Artifacts │ │ Traffic to pigknuckle.ai │ │ │ └─────────────────────────┘ └─────────────────────────────┘ │ │ ▲ │ │ │ │ ▼ │ │ │ ┌─────────────────────────────┐ │ │ └─────────────────────│ Compounding Domain │ │ │ │ Authority & Clicks │ │ │ └─────────────────────────────┘ │ └────────────────────────────────────────────────────────────────────────┘ Generative Engine Optimization (GEO) in 2026 In 2026, over 60% of search queries result in "zero-click" answers or direct synthesis by conversational AI engines [21]. To capture traffic, we must optimize for Generative Engine Optimization (GEO) and Answer Engine Optimization (AEO) [15, 24]. Retrieval-Augmented Generation (RAG) pipelines used by Perplexity, SearchGPT, Gemini, and Claude.ai rely heavily on structured data [17, 26]. Industry benchmarks demonstrate that pages containing structured schema markup are 36% to 40% more likely to be cited in generative summaries than unstructured pages [16, 25]. By serving clean JSON-LD and semantic HTML, we provide unambiguous facts (such as citations, software models, and research patterns) that LLMs can parse and attribute with high statistical confidence [17, 26]. Crawler Behavior and Directives Different crawlers require distinct optimization strategies [18, 23]: User-Facing Search/Citation Bots (ChatGPT-User, PerplexityBot, Claude-Web) fetch pages in real-time to answer user queries [14, 20]. They require immediate access to the /share/:token routes to extract metadata and generate citations [14, 20]. Model Training Bots (GPTBot, ClaudeBot, Google-Extended) scrape content in bulk to train future foundation models [18, 20]. While we must block these training bots from scraping our core application routes to protect intellectual property, we selectively allow them to index /share/:token with strict rate-limiting (Crawl-delay) to ensure our public artifacts remain embedded in their parametric knowledge bases [18, 23]. Traditional Search Bots (Googlebot, Bingbot) index pages for standard SERPs and Google's AI Overviews [18, 20]. They respect standard robots directives [18]. We also leverage the IndexIfEmbedded robots directive [31, 32]. Supported by Google, this tag ensures that if our shared artifacts are embedded via <iframe> on third-party partner sites, Google will index the artifact's content as part of the parent embedding page, amplifying our search footprint [31, 32]. Architecture Diagram The request flow distinguishes between human browsers and automated crawlers/unfurlers, routing both through the Cloudflare Worker to guarantee a consistent, pre-rendered HTML payload. Cloudflare Worker Specification The Cloudflare Worker intercepts all incoming traffic to pigknuckle.ai. It matches both the /share/:token and /og/:token.png patterns, fetches the raw HTML from the Cloudflare Pages deployment, retrieves the artifact data from the Supabase Edge Function, and uses HTMLRewriter to inject metadata. wrangler.toml Configuration name = "pigknuckle-edge-interceptor" main = "src/index.ts" compatibility_date = "2026-05-22" compatibility_flags = [ "nodejs_compat" ] Bindings [[routes]] pattern = "pigknuckle.ai/share/*" zone_name = "pigknuckle.ai" [[routes]] pattern = "pigknuckle.ai/og/*" zone_name = "pigknuckle.ai" [vars] SUPABASE_URL = "https://your-project-id.supabase.co" Secret variables must be set using: wrangler secret put SUPABASE_SERVICE_KEY SUPABASE_SERVICE_KEY = "service-role-key-here" Production-Ready TypeScript Worker (src/index.ts) import { ImageResponse } from "workers-og"; export interface Env { SUPABASE_URL: string; SUPABASE_SERVICE_KEY: string; } interface Citation { url: string; name: string; } interface ArtifactPayload { title: string null; summary: string null; created_at: string null; model: string null; pattern: string null; citations: Citation[] null; } // Dynamic OG Image Generator Logic (Integrated into Single Worker Router) async function handleOgImage(request: Request, env: Env, token: string): Promise<Response> { const fallbackImage = () => fetch("https://pigknuckle.ai/assets/default-og.png"); try { const supabaseUrl = ${env.SUPABASE_URL}/functions/v1/get-shared-result?token=${token}; const supabaseResponse = await fetch(supabaseUrl, { method: "GET", headers: { "Authorization": Bearer ${env.SUPABASE_SERVICE_KEY}, "Content-Type": "application/json" } }); if (!supabaseResponse.ok) return fallbackImage(); const artifact = await supabaseResponse.json() as ArtifactPayload; if (!artifact) return fallbackImage(); const title = artifact.title "Untitled Artifact"; const rawSummary = artifact.summary "No summary available."; const description = rawSummary.length > 155 ? ${rawSummary.substring(0, 152).trim()}... : rawSummary; const model = artifact.model ?? "Unknown Model"; const pattern = artifact.pattern ?? "Standard"; // HTML Template rendered to PNG (1200x630) with Pig Knuckle's bold branding [11] const html = <div style="display: flex; flex-direction: column; justify-content: space-between; height: 630px; width: 1200px; padding: 60px; background-color: #0c0c0e; font-family: sans-serif; border: 12px solid #ff3e3e; box-sizing: border-box;"> <div style="display: flex; flex-direction: column; gap: 20px;"> <div style="display: flex; align-items: center; gap: 16px;"> <span style="background-color: #ff3e3e; color: #000000; font-size: 20px; font-weight: 900; padding: 6px 16px; border-radius: 4px; text-transform: uppercase; letter-spacing: 1.5px;">Pig Knuckle</span> <span style="color: #8e8e93; font-size: 20px; font-weight: 600; letter-spacing: 0.5px;">AI Outcome Engine</span> </div> <h1 style="font-size: 58px; font-weight: 900; color: #ffffff; line-height: 1.15; margin: 0; padding-top: 15px; display: flex; flex-wrap: wrap;"> ${title} </h1> <p style="font-size: 24px; color: #a1a1aa; line-height: 1.45; margin: 0; display: flex; flex-wrap: wrap;"> ${description} </p> </div> <div style="display: flex; justify-content: space-between; align-items: center; border-top: 2px solid #27272a; padding-top: 30px;"> <div style="display: flex; align-items: center; gap: 40px;"> <div style="display: flex; flex-direction: column;"> <span style="color: #71717a; font-size: 14px; text-transform: uppercase; letter-spacing: 1px; font-weight: 700;">Model Engine</span> <span style="color: #ffffff; font-size: 20px; font-weight: 700; margin-top: 4px;">${model}</span> </div> <div style="display: flex; flex-direction: column;"> <span style="color: #71717a; font-size: 14px; text-transform: uppercase; letter-spacing: 1px; font-weight: 700;">Research Pattern</span> <span style="color: #ffffff; font-size: 20px; font-weight: 700; margin-top: 4px; text-transform: capitalize;">${pattern}</span> </div> </div> <div style="color: #ff3e3e; font-size: 28px; font-weight: 900; letter-spacing: -1px; text-transform: uppercase;">STOP THE SLOP.</div> </div> </div> ; return new ImageResponse(html, { width: 1200, height: 630, headers: { "Cache-Control": "public, max-age=86400, stale-while-revalidate=604800" } }); } catch (error) { return fallbackImage(); } } export default { async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> { const url = new URL(request.url); const path = url.pathname; // Route: OG Image Generation const ogRegex = /^\/og\/([A-Za-z0-9]+)\.png$/; const ogMatch = path.match(ogRegex); if (ogMatch) { return handleOgImage(request, env, ogMatch[1]); } // Route: Share Interception const shareRegex = /^\/share\/([A-Za-z0-9]+)\/?$/; const shareMatch = path.match(shareRegex); // Pass through all other routes unmodified to the Cloudflare Pages asset if (!shareMatch) { return fetch(request); } const token = shareMatch[1]; // Rewrite the URL to fetch the static SPA shell from the origin const shellUrl = new URL(request.url); shellUrl.pathname = "/index.html"; const originalResponse = await fetch(shellUrl.toString(), { method: "GET", headers: request.headers }); if (!originalResponse.ok) { return originalResponse; } try { // Fetch the artifact payload from the Supabase Edge Function const supabaseUrl = ${env.SUPABASE_URL}/functions/v1/get-shared-result?token=${token}; // Enforce a strict 3-second timeout for the database fetch to guarantee low edge latency const controller = new AbortController(); const timeoutId = setTimeout(() => controller.abort(), 3000); const supabaseResponse = await fetch(supabaseUrl, { method: "GET", headers: { "Authorization": Bearer ${env.SUPABASE_SERVICE_KEY}, "Content-Type": "application/json" }, signal: controller.signal }); clearTimeout(timeoutId); if (!supabaseResponse.ok) { // Return the SPA shell with a 404 status code so search engines don't index invalid tokens return new Response(originalResponse.body, { status: 404, headers: originalResponse.headers }); } const artifact = await supabaseResponse.json() as ArtifactPayload; if (!artifact) { return originalResponse; } // Defensive Null-Coalescing Logic const title = artifact.title "Shared Artifact"; const rawSummary = artifact.summary "No summary available for this Pig Knuckle artifact."; const description = rawSummary.length > 155 ? ${rawSummary.substring(0, 152).trim()}... : rawSummary; const createdAt = artifact.created_at new Date().toISOString(); const model = artifact.model ?? "Unknown Model"; const pattern = artifact.pattern ?? "Standard Analysis"; const citations = artifact.citations ?? []; const canonicalUrl = https://pigknuckle.ai/share/${token}; const ogImageUrl = https://pigknuckle.ai/og/${token}.png; // Construct JSON-LD Payload (Schema.org) const jsonLd = { "@context": "https://schema.org", "@graph": [ { "@type": "Article", "@id": ${canonicalUrl}#article, "isPartOf": { "@type": "WebPage", "@id": canonicalUrl, "url": canonicalUrl, "name": ${title} — Pig Knuckle }, "headline": title, "description": description, "datePublished": createdAt, "dateModified": createdAt, // Satisfies Google Rich Results recommendations "image": ogImageUrl, "author": { "@type": "Organization", "name": "Pig Knuckle", "url": "https://pigknuckle.ai" }, "publisher": { "@type": "Organization", "name": "Pig Knuckle", "logo": { "@type": "ImageObject", "url": "https://pigknuckle.ai/logo.png" } }, "mainEntityOfPage": canonicalUrl, "keywords": pattern, "mentions": { "@type": "SoftwareApplication", "name": model, "applicationCategory": "Artificial Intelligence" }, "citation": citations.map((c) => ({ "@type": "CreativeWork", "name": c.name "Source Document", "url": c.url "#" })) }, { "@type": "BreadcrumbList", "@id": ${canonicalUrl}#breadcrumb, "itemListElement": [ { "@type": "ListItem", "position": 1, "name": "Home", "item": "https://pigknuckle.ai" }, { "@type": "ListItem", "position": 2, "name": "Share", "item": "https://pigknuckle.ai/share" }, { "@type": "ListItem", "position": 3, "name": title, "item": canonicalUrl } ] } ] }; // Escape '<' to prevent XSS injection via '</script>' in user-generated content const jsonLdString = JSON.stringify(jsonLd).replace(/</g, "\\u003c"); // HTMLRewriter Handlers to inject tags cleanly class TitleRemover { element(element: Element) { element.remove(); } } class HeadHandler { element(element: Element) { // Inject Title element.append(<title>${title} — Pig Knuckle</title>, { html: true }); // Inject Meta Robots with IndexIfEmbedded for iframe indexing support element.append(<meta name="robots" content="index, follow, max-image-preview:large, indexifembedded" />, { html: true }); // Inject OpenGraph Tags element.append(<meta property="og:title" content="${title}" />, { html: true }); element.append(<meta property="og:description" content="${description}" />, { html: true }); element.append(<meta property="og:url" content="${canonicalUrl}" />, { html: true }); element.append(<meta property="og:type" content="article" />, { html: true }); element.append(<meta property="og:image" content="${ogImageUrl}" />, { html: true }); element.append(<meta property="og:image:width" content="1200" />, { html: true }); element.append(<meta property="og:image:height" content="630" />, { html: true }); element.append(<meta property="og:site_name" content="Pig Knuckle" />, { html: true }); element.append(<meta property="article:published_time" content="${createdAt}" />, { html: true }); element.append(<meta property="article:author" content="https://pigknuckle.ai" />, { html: true }); // Inject Twitter Card Tags element.append(<meta name="twitter:card" content="summary_large_image" />, { html: true }); element.append(<meta name="twitter:title" content="${title}" />, { html: true }); element.append(<meta name="twitter:description" content="${description}" />, { html: true }); element.append(<meta name="twitter:image" content="${ogImageUrl}" />, { html: true }); // Inject Canonical Link element.append(<link rel="canonical" href="${canonicalUrl}" />, { html: true }); // Inject JSON-LD Schema element.append(<script type="application/ld+json">${jsonLdString}</script>, { html: true }); } } // Transform the HTML stream const rewriter = new HTMLRewriter() .on("title", new TitleRemover()) .on("head", new HeadHandler()); const enrichedResponse = rewriter.transform(originalResponse); // Clone response to append custom caching headers const finalResponse = new Response(enrichedResponse.body, enrichedResponse); finalResponse.headers.set( "Cache-Control", "public, max-age=60, stale-while-revalidate=300" ); return finalResponse; } catch (error) { // Graceful fallback on execution error: serve the 200 OK SPA shell return originalResponse; } } }; Schema.org JSON-LD Template To ensure validation against https://validator.schema.org and Google’s Rich Results test, the injected JSON-LD block implements a multi-entity graph linking the Article and BreadcrumbList schemas [26]. Complete JSON-LD Schema { "@context": "https://schema.org", "@graph": [ { "@type": "Article", "@id": "https://pigknuckle.ai/share/g50iXJnuFBn9#article", "isPartOf": { "@type": "WebPage", "@id": "https://pigknuckle.ai/share/g50iXJnuFBn9", "url": "https://pigknuckle.ai/share/g50iXJnuFBn9", "name": "The Death of PowerPoint: Automated Narrative Synthesis — Pig Knuckle" }, "headline": "The Death of PowerPoint: Automated Narrative Synthesis", "description": "We analyze how enterprise teams are replacing slide decks with dynamic, AI-generated research artifacts, accelerating decision cycles by 14x.", "datePublished": "2026-05-22T13:48:00.000Z", "dateModified": "2026-05-22T13:48:00.000Z", "image": "https://pigknuckle.ai/og/g50iXJnuFBn9.png", "author": { "@type": "Organization", "name": "Pig Knuckle", "url": "https://pigknuckle.ai" }, "publisher": { "@type": "Organization", "name": "Pig Knuckle", "logo": { "@type": "ImageObject", "url": "https://pigknuckle.ai/logo.png" } }, "mainEntityOfPage": "https://pigknuckle.ai/share/g50iXJnuFBn9", "keywords": "deep-research", "mentions": { "@type": "SoftwareApplication", "name": "claude-3-5-sonnet", "applicationCategory": "Artificial Intelligence" }, "citation": [ { "@type": "CreativeWork", "name": "Gartner Enterprise AI Report 2026", "url": "https://www.gartner.com/en/documents/enterprise-ai-2026" }, { "@type": "CreativeWork", "name": "MIT Sloan Slide-Free Workplaces Study", "url": "https://sloanreview.mit.edu/article/slide-free-workplaces" } ] }, { "@type": "BreadcrumbList", "@id": "https://pigknuckle.ai/share/g50iXJnuFBn9#breadcrumb", "itemListElement": [ { "@type": "ListItem", "position": 1, "name": "Home", "item": "https://pigknuckle.ai" }, { "@type": "ListItem", "position": 2, "name": "Share", "item": "https://pigknuckle.ai/share" }, { "@type": "ListItem", "position": 3, "name": "The Death of PowerPoint: Automated Narrative Synthesis", "item": "https://pigknuckle.ai/share/g50iXJnuFBn9" } ] } ] } Schema Validation Fields (Required vs. Recommended) Schema Property Required / Recommended Validation Purpose headline Required Maps to title. Must not exceed 110 characters. datePublished Required Maps to created_at. Must be ISO 8601 format. dateModified Required Maps to created_at (or update timestamp). Prevents Google Rich Results warnings. image Required Maps to dynamic OG image. Crucial for Google Discover and Google Search Rich Snippets. publisher Required Maps to Pig Knuckle Organization. Requires a valid logo image URL. author Required Maps to Pig Knuckle Organization (or user profile if added later). description Recommended Maps to summary. Used for rich snippet generation. mentions Recommended Maps to model. Helps LLMs categorize the software application used [26]. keywords Recommended Maps to pattern. Aids thematic categorization. citation Recommended Maps to citations[]. Highly valued by Perplexity and SearchGPT for verification and source mapping [26]. Semantic HTML Recommendations for ShareView.tsx To ensure that search engines executing JavaScript (like Googlebot's second pass) and direct LLM web retrievers parse the page structure correctly, we must apply Microdata attributes directly to our React components. These changes are entirely additive, introducing zero visual or layout modifications. Updated ShareView.tsx import React from 'react'; import { ShareMetadata } from './ShareMetadata'; import { CitationPanel } from './CitationPanel'; interface Artifact { token: string; title: string; summary: string; created_at: string; model: string; pattern: string; citations: Array<{ url: string; name: string }>; } export const ShareView: React.FC<{ artifact: Artifact }> = ({ artifact }) => { return ( <article itemScope itemType="https://schema.org/Article" className="max-w-4xl mx-auto px-4 py-8 bg-black text-white" {/ Hidden Microdata tags for fields not visually rendered in the main layout /} <link itemProp="mainEntityOfPage" href={window.location.href} /> <link itemProp="image" href={https://pigknuckle.ai/og/${artifact.token}.png} /> <header className="border-b border-zinc-800 pb-6 mb-8"> <h1 itemProp="headline" className="text-4xl font-extrabold tracking-tight text-white sm:text-5xl" {artifact.title} </h1> <ShareMetadata createdAt={artifact.created_at} model={artifact.model} pattern={artifact.pattern} /> </header> <div itemProp="description" className="prose prose-invert max-w-none text-zinc-300 text-lg leading-relaxed mb-12" {artifact.summary} </div> <CitationPanel citations={artifact.citations} /> </article> ); }; Updated ShareMetadata.tsx import React from 'react'; interface ShareMetadataProps { createdAt: string; model: string; pattern: string; } export const ShareMetadata: React.FC<ShareMetadataProps> = ({ createdAt, model, pattern }) => { const formattedDate = new Date(createdAt).toLocaleDateString(undefined, { year: 'numeric', month: 'long', day: 'numeric', }); return ( <div className="flex flex-wrap items-center gap-4 text-sm text-zinc-500 mt-4"> <div> Published on:{' '} <time dateTime={createdAt} itemProp="datePublished" className="font-medium text-zinc-300" {formattedDate} </time> <meta itemProp="dateModified" content={createdAt} /> </div> <span className="text-zinc-700">•</span> <div itemProp="mentions" itemScope itemType="https://schema.org/SoftwareApplication"> Engine:{' '} <span itemProp="name" className="font-medium text-zinc-300"> {model} </span> <meta itemProp="applicationCategory" content="Artificial Intelligence" /> </div> <span className="text-zinc-700">•</span> <div> Pattern:{' '} <span itemProp="keywords" className="font-medium text-zinc-300 capitalize"> {pattern} </span> </div> </div> ); }; Updated CitationPanel.tsx (Inside /components) import React from 'react'; interface Citation { url: string; name: string; } export const CitationPanel: React.FC<{ citations: Citation[] }> = ({ citations }) => { if (!citations citations.length === 0) return null; return ( <section className="border-t border-zinc-800 pt-8 mt-8"> <h2 className="text-xl font-bold text-white mb-4">Verified Sources & Citations</h2> <ul className="space-y-3"> {citations.map((citation, idx) => ( <li key={idx} itemProp="citation" itemScope itemType="https://schema.org/CreativeWork" className="flex items-start gap-2" <span className="text-red-500 font-bold">[{idx + 1}]</span> <a itemProp="url" href={citation.url} target="_blank" rel="noopener noreferrer" className="text-zinc-400 hover:text-red-400 underline transition-colors" <span itemProp="name">{citation.name}</span> </a> </li> ))} </ul> </section> ); }; robots.txt and AI Crawler Policy Our robots.txt strategy is designed to maximize visibility in AI citation and search engines, allow traditional search indexing, and protect our application routes from data brokers and bulk training scrapers [18, 23]. Complete robots.txt # robots.txt for pigknuckle.ai (May 2026) User-Facing AI Search & Citation Engines (High-Priority Referral Traffic) User-agent: ChatGPT-User Allow: / Allow: /share/ Disallow: /app/ Disallow: /api/ Disallow: /settings/ User-agent: PerplexityBot Allow: / Allow: /share/ Disallow: /app/ Disallow: /api/ Disallow: /settings/ User-agent: Claude-Web Allow: / Allow: /share/ Disallow: /app/ Disallow: /api/ Disallow: /settings/ Traditional Search Engine Crawlers (Organic Traffic & AI Overviews) User-agent: Googlebot Allow: / Allow: /share/ Disallow: /app/ Disallow: /api/ Disallow: /settings/ User-agent: Bingbot Allow: / Allow: /share/ Disallow: /app/ Disallow: /api/ Disallow: /settings/ User-agent: Applebot Allow: / Allow: /share/ Disallow: /app/ Disallow: /api/ Disallow: /settings/ AI Model Training Crawlers (Controlled Access with Crawl-Delay) User-agent: GPTBot Allow: /share/ Disallow: /app/ Disallow: /api/ Disallow: /settings/ Disallow: / Note: GPTBot ignores the Crawl-delay directive entirely. User-agent: ClaudeBot Crawl-delay: 2 Allow: /share/ Disallow: /app/ Disallow: /api/ Disallow: /settings/ Disallow: / User-agent: Google-Extended Disallow: / # Opt-out of Google model training while keeping Googlebot indexing active User-agent: anthropic-ai Crawl-delay: 2 Allow: /share/ Disallow: /app/ Disallow: /api/ Disallow: /settings/ Disallow: / Global Default Rule (Block Scrapers & Protect Origin) User-agent: * Allow: / Allow: /share/ Disallow: /app/ Disallow: /api/ Disallow: /settings/ Sitemap Directive Sitemap: https://pigknuckle.ai/sitemap.xml Dynamic Sitemap Endpoint Spec (S