๐ Landing Site Overview
Public marketing surface for AceSense โ discovery, conversion, and AI-search visibility.
:::tip TL;DR
- Repo: github.com/Acesense/acesense-landing
- Live: acesense.io (Firebase Hosting target
landingโ siteacesense-prod) - Stack: React 19 + Vite (Rolldown) + React Router + react-helmet-async + react-markdown
- Content: 49 blog posts + 37 marketing pages, all markdown-driven with frontmatter
- SSG: post-build prerender via Puppeteer โ every content route gets static HTML for SEO + AI crawlers
- Analytics: PostHog (EU) + Firebase Analytics (consent-mode v2) :::
๐ What it doesโ
The landing surface has three jobs:
- Conversion โ route users to the App Store and web app, show pricing, surface a sample post-match report.
- Discovery โ rank on Google + AI search for the question clusters described in SEO & Discovery, targeting evidence-backed tennis video analysis queries.
- AI-search citation โ every detail page ships pre-rendered HTML with
Article/TechArticle/BlogPosting/FAQPageJSON-LD so PerplexityBot, ClaudeBot, OAI-SearchBot, and ChatGPT-User can ground answers in our content without executing JavaScript. - Agent discovery โ
/agentsis an agent-facing surface advertising the public API catalog, MCP endpoint, and x402 agent-commerce path (see agent API).
๐ ๏ธ Tech stackโ
| Technology | Version | Purpose |
|---|---|---|
| React | 19.2.0 | UI framework |
| Vite (Rolldown) | 7.2.5 | Build tool |
| TypeScript | 5.9.3 | Type safety |
| react-router-dom | 7.x | Client routing for content tree |
| react-helmet-async | latest | Per-route metadata |
| react-markdown + remark-gfm + rehype-raw | latest | Markdown rendering |
| tiny local parser | n/a | YAML-ish frontmatter parsing at app build time |
| Puppeteer | latest (devDep) | Build-time SSG prerender |
PostHog (posthog-js + @posthog/react) | latest | Product analytics, EU host |
| Firebase | 12.x | Hosting, Analytics (consent-mode v2) |
๐๏ธ Public route mapโ
/ โ homepage (App.tsx, hero + App Store badge + sample-report CTA)
/blog โ blog index (49 posts)
/blog/:slug
/compare โ comparison hub
/compare/:slug โ swingvision, pb-vision, baseline-vision, playsight, onform, topcourt, pricing-grid
/alternatives โ alternatives hub
/alternatives/:slug โ swingvision, onform, topcourt
/use-cases โ persona hub
/use-cases/:slug โ club-players, junior-coaches, parents-junior-tennis, adult-returners, coaches-async-review
/features โ features hub
/features/:slug โ shot-detection, ball-tracking, court-heatmap, stroke-quality, coaching-report
/how-to โ how-to hub
/how-to/:slug โ film-your-tennis-match, record-your-serve, share-report-with-coach
/how-it-works โ pipeline pillar (TechArticle schema)
/accuracy โ published methodology + benchmarks
/pricing โ real route, not anchor
/faq โ FAQPage-schema FAQ
/changelog
/android โ Android-wedge landing
/ios โ iOS landing
/biomechanics โ biomechanics-keyword landing
/sweden โ Sweden-region landing (EN/SV bilingual)
/examples โ analysis sample gallery
/sample-report โ static post-match report sample
/agents โ agent-discovery surface (API catalog, MCP, x402)
/about
/contact, /privacy, /terms, /accessibility โ static .html (Firebase rewrites)
All content + static routes are emitted into sitemap.xml (count is derived at build time from the content tree + vite.config.ts dynamic routes). The * catch-all renders a real 404 page.
๐ Source layoutโ
acesense-landing/
โโโ public/
โ โโโ robots.txt โ all bots allowed (search, AI search, training)
โ โโโ llms.txt โ AI-agent content map
โ โโโ og-image.png โ 1200ร630 brand card
โ โโโ *.html โ static contact/privacy/terms/accessibility
โโโ src/
โ โโโ main.tsx โ root (HelmetProvider + BrowserRouter + PostHogProvider)
โ โโโ AppRouter.tsx โ all routes + lazy chunks
โ โโโ App.tsx โ homepage (hero + App Store badge + sample-report CTA + cookie banner)
โ โโโ pages/
โ โ โโโ BlogIndexPage.tsx
โ โ โโโ BlogPostPage.tsx
โ โ โโโ HubPage.tsx โ /compare, /alternatives, /use-cases, /features, /how-to
โ โ โโโ ContentPage.tsx โ detail pages (markdown + frontmatter-driven)
โ โโโ components/
โ โ โโโ layout/
โ โ โ โโโ PageShell.tsx โ header/footer/Helmet wrapper
โ โ โ โโโ MarkdownBody.tsx โ strips leading H1, routes internal links
โ โ โ โโโ page-shell.css
โ โ โโโ CookieConsent.tsx
โ โโโ lib/
โ โ โโโ content.ts โ import.meta.glob loader for markdown files
โ โโโ content/
โ โ โโโ blog/ โ 49 .md files
โ โ โโโ compare/ โ 7 .md files
โ โ โโโ alternatives/ โ 3 .md files
โ โ โโโ use-cases/ โ 5 .md files
โ โ โโโ features/ โ 5 .md files
โ โ โโโ how-to/ โ 3 .md files
โ โ โโโ static/ โ how-it-works, accuracy, pricing, faq, changelog,
โ โ android, ios, examples, about, biomechanics,
โ โ sweden, agents, founder, sample-report
โ โโโ firebase.ts โ Firebase Analytics + consent-mode helpers
โโโ scripts/
โ โโโ prerender.mjs โ post-build Puppeteer SSG
โโโ vite.config.ts โ sitemap plugin, dynamic-routes from content
โโโ firebase.json โ rewrites for static .html + SPA fallback
โ๏ธ Build pipelineโ
The prerender step is non-optional for AI-bot visibility. Skipping it means PerplexityBot et al. see only the SPA shell.
๐ค AI-discovery infrastructureโ
| Asset | Purpose | Location |
|---|---|---|
robots.txt | Per-bot allow rules โ all bots welcome | public/robots.txt |
llms.txt | Content map for AI agents | public/llms.txt |
sitemap.xml | All indexable URLs (derived from content tree at build) | emitted by scripts/prerender.mjs |
| Per-route HTML | Pre-rendered with page-specific <title>, description, OG, JSON-LD | dist/<route>/index.html |
| Schema | Organization + WebSite + SoftwareApplication on /; Article/TechArticle/BlogPosting/FAQPage + BreadcrumbList on each detail | inline <script type="application/ld+json"> |
Cloudflare note. acesense.io is fronted by Cloudflare. Cloudflare's Content Signals feature can override the origin's robots.txt. Manage via Cloudflare dashboard โ Security โ Bots โ Manage AI Bots.
See reference/seo-discovery for the full surface.
๐ Analyticsโ
| Tool | Surface | Why |
|---|---|---|
| PostHog (EU) | All routes | Cross-surface user journey, autocapture, no session recording on landing |
| Firebase Analytics | All routes | GDPR consent-mode v2, Google Ads parity if we ever run paid |
PostHog token + host are in .env (gitignored). See reference/analytics for the cross-surface setup.
๐ Common commandsโ
cd acesense-landing
pnpm install
pnpm dev # vite dev server
pnpm build # tsc + vite build + SSG prerender
pnpm preview # serve dist/ locally
firebase deploy --only hosting:landing
๐ Related docsโ
- SEO discovery surface โ sitemap, robots, llms.txt, JSON-LD, SSG
- Cross-surface analytics โ PostHog setup across all 6 surfaces
- ADR-0005: PostHog EU as product analytics
- Architecture overview