Skip to main content

๐ŸŒ 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 โ†’ site acesense-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:

  1. Conversion โ€” route users to the App Store and web app, show pricing, surface a sample post-match report.
  2. Discovery โ€” rank on Google + AI search for the question clusters described in SEO & Discovery, targeting evidence-backed tennis video analysis queries.
  3. AI-search citation โ€” every detail page ships pre-rendered HTML with Article / TechArticle / BlogPosting / FAQPage JSON-LD so PerplexityBot, ClaudeBot, OAI-SearchBot, and ChatGPT-User can ground answers in our content without executing JavaScript.
  4. Agent discovery โ€” /agents is an agent-facing surface advertising the public API catalog, MCP endpoint, and x402 agent-commerce path (see agent API).

๐Ÿ› ๏ธ Tech stackโ€‹

TechnologyVersionPurpose
React19.2.0UI framework
Vite (Rolldown)7.2.5Build tool
TypeScript5.9.3Type safety
react-router-dom7.xClient routing for content tree
react-helmet-asynclatestPer-route metadata
react-markdown + remark-gfm + rehype-rawlatestMarkdown rendering
tiny local parsern/aYAML-ish frontmatter parsing at app build time
Puppeteerlatest (devDep)Build-time SSG prerender
PostHog (posthog-js + @posthog/react)latestProduct analytics, EU host
Firebase12.xHosting, 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โ€‹

AssetPurposeLocation
robots.txtPer-bot allow rules โ€” all bots welcomepublic/robots.txt
llms.txtContent map for AI agentspublic/llms.txt
sitemap.xmlAll indexable URLs (derived from content tree at build)emitted by scripts/prerender.mjs
Per-route HTMLPre-rendered with page-specific <title>, description, OG, JSON-LDdist/<route>/index.html
SchemaOrganization + WebSite + SoftwareApplication on /; Article/TechArticle/BlogPosting/FAQPage + BreadcrumbList on each detailinline <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โ€‹

ToolSurfaceWhy
PostHog (EU)All routesCross-surface user journey, autocapture, no session recording on landing
Firebase AnalyticsAll routesGDPR 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