# SaaStock — SEO, AEO & GEO Master Playbook The single reference for how every page on saastock.com should be built, linked, and optimized for traditional search, AI answer engines, and generative search. --- ## 1. URL Architecture ``` saastock.com/ ├── europe/ ← Series hub │ ├── 2016/ ← Historical event page (the only per-event route) │ ├── 2017/ │ ├── ... │ ├── 2025/ │ └── 2026/ ← Upcoming event │ ├── usa/ ← Series hub │ ├── 2023/ │ ├── 2024/ │ ├── 2025/ │ └── 2026/ │ ├── local/ ← Local events hub │ ├── amsterdam/ ← City rollup │ ├── barcelona/ │ ├── dublin/ │ └── ... │ ├── speakers/ ← Global speaker directory (filter via ?event=) │ ├── sarah-kiley/ ← Individual speaker profile │ ├── mark-walker/ │ └── ... │ ├── recordings/ ← Global recordings library (filter via ?event=) │ ├── podcast/ ← SaaS Revolution Show hub │ └── [episode-slug]/ ← Individual episode with transcript │ ├── about/ │ └── our-story/ ← Timeline narrative │ └── llms.txt ← Site-wide AI summary ``` **Rules:** - Event pages live under their series (`/usa/2026`, `/europe/2024`), never at root. The event page itself is the **only** per-event route — there is no `/usa/2025/speakers/` and no `/usa/2025/talks/`. Don't add them. - Speaker profiles live at `/speakers/[slug]` globally, not nested under events. A speaker speaks at multiple events — their profile is the canonical page, and each event links to it. - Recordings are surfaced two ways: (1) up to 6 **featured** recordings embedded directly on the event page itself, (2) the complete archive at the global `/recordings/` hub, deep-linked from each event page via `/recordings/?event=`. There are no per-talk pages — the canonical home of every recording is the event page (which embeds the YouTube video) and the global hub. - Use `/recordings/`, not `/talks/`. Users organically search "SaaStock 2022 recordings", not "talks". The URL slug and user-facing copy ("All {event} recordings →", "Featured recordings", "See all recordings") all follow this. - Podcast episodes live at `/podcast/[slug]`. They're not tied to a specific event. - The `/speakers/` and `/recordings/` hubs are index pages that aggregate across all events and all time. Tag filters via `?event=` give event-scoped views without creating thin per-event index pages that would split link equity. (One filtered view per event would be ~25 near-duplicate pages competing for the same queries — bad for SEO.) **Hard rule: never link to a route that does not exist.** Before adding a CTA, anchor, or quicklink, confirm the destination route is built. If it isn't, either build the route, anchor to an on-page section, or drop the CTA. A 404 from a featured CTA is worse than no CTA at all. This was the failure mode that produced the `/europe/2022/speakers/` and `/europe/2022/talks/` 404s — the playbook described those routes as if they existed, and the rendered event pages linked to them, but they were never built. --- ## 2. Page Types and Content Requirements ### 2a. Historical Event Page (`/usa/2026`) This is the page we've already designed. Requirements: - **Cinematic hero — full-bleed silent video (or photo fallback) with ONLY the eyebrow + H1 overlaid.** The video is the most important visual element of the page. Everything else (sub-headline, venue/date meta row, quicklinks, stats) moves into a continuous dark band immediately below the hero so the video reads at full strength. The hero `min-h-[clamp(440px,62vh,680px)]` so the sizzle has presence; the only dark overlay is a localized bottom-anchored gradient (~lower 60%) for H1 legibility — no section-wide tint. Earlier builds had a 2-column hero with a YouTube iframe on the right, then a 5-col grid with all metadata stuffed into the left 2 cols; both were rejected because the supporting text fought the video for attention. The rule now is: `hero = video + eyebrow + H1`, full stop. - **Hero background video (the silent loop).** When an event has an official sizzle, encode it as a silent autoplay-loop background. Specs: - 720p H.264 MP4 + VP9 WebM, audio stripped at encode time (`ffmpeg -an`), `+faststart` on the MP4. - Files live next to the event's gallery, e.g. `/europe//gallery/video/video--sizzle-recap-hero.{mp4,webm}`. - Wired via `EventData.hero.videoSources: { mp4?: string; webm?: string }`. The hero photo (`data.hero.image`) doubles as both the `