diff --git a/CLAUDE.md b/CLAUDE.md index d3977f1..ac4ae3c 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -55,6 +55,39 @@ This repo uses **release-please**. Since GitHub squash-merges use the PR title a - **Deployment**: Cloudflare Pages (consistent with rest of org) - **Domain**: `wavekat.com` — DNS to be pointed at Cloudflare Pages once site is ready +## SEO & GEO — every new page must be both + +This site is optimized for classic search (SEO) **and** generative answer engines (GEO — being quoted by ChatGPT, Perplexity, Google AI Overviews, Claude). The two overlap but aren't identical: SEO wants crawlable, well-described, linkable pages; GEO wants self-contained, factual, extractable passages an LLM can lift verbatim. Build for both on every page. + +### What's already wired (don't reinvent it) + +- **`Base.astro` is the SEO baseline** (established in #81, `feat(seo)`). It emits the canonical URL, ``, the `robots` directive (with a `noindex` prop to opt a page out of indexing), the full Open Graph + Twitter card set, light/dark `theme-color`, and the sitewide `Organization` + `WebSite` JSON-LD graph (`@id`s `https://wavekat.com/#organization` and `#website`). It also takes `ogType` / `article` props so child layouts can emit article semantics. Every layout (`Voice`, `Post`, `Docs`) wraps `Base`, so every page gets this for free. +- **Sitemap + robots are automatic.** `@astrojs/sitemap` generates `sitemap-index.xml` at build from the `site` in `astro.config.mjs`; `public/robots.txt` allows all crawlers (including AI crawlers — keep it open for GEO) and points at the sitemap. A new page under `src/pages/` is in the sitemap with zero extra work. +- **`og.png`** is generated 1200×630 from the brand SVG by `make sync`. Pages share it unless they pass their own `ogImage`. + +### Rules for every new page + +1. **Always pass a real `title` and `description`** to the layout — they drive `