Appearance
Marketing Site Overview
The marketing site is a Next.js 15 App Router application. It serves code-driven public pages, Sanity-backed blog routes, and a separate early-access experience, then builds for Cloudflare Workers through OpenNext.
Architecture Map
text
Next.js App Router
|-- (main) route group
| |-- shared public shell
| |-- code-driven marketing pages
| `-- Sanity-backed blog routes
`-- (early-access) route group
`-- standalone launch page and signup form
Shared services
|-- @jubiloop/ui components and styles
|-- Tuyau API client
|-- TanStack Query provider
|-- metadata and JSON-LD helpers
`-- structured logger| Concern | Main implementation | Details |
|---|---|---|
| Routes and layouts | src/app/ | This overview |
| Static and CMS content ownership | src/data/, src/utils/strings.ts, src/sanity/ | Content Management |
| Blog delivery | Blog routes, resource functions, client filtering | Blog System |
| Early-access route and form | (early-access), early-access components, launch redirect | Early Access |
| Metadata and structured data | src/utils/metadata/, src/utils/schema/, src/components/seo/ | SEO and Schema |
| Shared UI contract | @jubiloop/ui | UI Components Package |
Route Groups And Shells
The (main) layout supplies the public shell: skip link, navigation, main-content landmark, footer, providers, health check, and toaster. SiteNavigation, Navbar, and Footer use link definitions from src/data/site-navigation.ts, while repeated labels and copy come from src/utils/strings.ts.
The (early-access) layout is separate. It shares global styles, locally bundled fonts, TanStack Query setup, and health checking, but the page renders its own header, footer, signup composition, and toaster.
Server Components are the default in both groups. Add a client boundary only for browser state, event handlers, or hooks. The blog routes fetch Sanity content in async Server Components, while search, filtering, pagination, and sharing controls run in focused client components.
Data Sources
The site has three data paths:
- Code-driven content from route components, focused data modules, and
src/utils/strings.ts. - Published blog content from Sanity through resource functions under
src/utils/blog/. - Server API calls through the configured Tuyau React Query client in
src/lib/api/tuyau.ts.
Health checking and newsletter subscription use Tuyau. The public marketing app does not configure the Better Auth client or session state.
UI And Styling Context
Marketing components import shared controls from @jubiloop/ui. src/app/globals.css imports the shared stylesheet and scans marketing source, and both route-group layouts load the local Manrope and Newsreader font files. The site explicitly applies the light theme; it has no theme provider or theme toggle.
The complete package export, token, typography, contrast, and stylesheet contract lives in UI Components Package.
Key Paths
| Path | Responsibility |
|---|---|
apps/marketing/src/app/ | App Router pages, route groups, layouts, metadata routes, and loading states |
apps/marketing/src/components/ | Public shell, page sections, forms, blog UI, and SEO components |
apps/marketing/src/data/ | Navigation and focused structured page data |
apps/marketing/src/sanity/ | Sanity client, schemas, Studio structure, and image builder |
apps/marketing/src/utils/blog/ | GROQ-backed resource functions and blog transformations |
apps/marketing/src/utils/metadata/ | Page metadata and blog excerpts |
apps/marketing/src/utils/schema/ | JSON-LD graph builders |
apps/marketing/src/lib/api/tuyau.ts | Public API client and TanStack Query options |
Runtime And Deployment
next.config.ts configures shared UI transpilation, external image hosts, local development origins, and the optional early-access redirect. open-next.config.ts and wrangler.jsonc configure the Cloudflare build output and runtime.
Deployment procedures and environment configuration belong in the Infrastructure Deployment documentation.
Development Commands
Run from apps/marketing/:
bash
pnpm run dev
pnpm run test
pnpm run lint
pnpm run check-types
pnpm run build
pnpm run build:cloudflare