Public-facing marketing, blog, and documentation site for the ResQ platform. Built with Next.js 16 (App Router), deployed to Cloudflare Workers via OpenNext, and optimized for Core Web Vitals and edge performance.
Locales: English, Spanish, Chinese, Hindi, Arabic (RTL)
flowchart LR
Browser -->|HTTPS| CF["Cloudflare CDN"]
CF -->|Static assets| Assets["Static HTML/CSS/JS"]
CF -->|Dynamic routes| Worker["Cloudflare Worker"]
Worker -->|Locale routing| MW["next-intl Middleware"]
MW --> SSR["Server Components"]
SSR --> UI["React 19 UI"]
Worker -->|/api/*| Elysia["Elysia API"]
Elysia --> Health["/health"]
Elysia --> Status["/status"]
flowchart TD
Push["git push main"] --> CI
subgraph CI["CI (parallel)"]
Build["Build"]
Test["bun test"]
Lint["biome lint"]
end
CI -->|all pass| Deploy
subgraph Deploy["Deploy"]
ON["opennextjs-cloudflare build"] --> Wrangler["wrangler deploy"]
end
Wrangler --> Live["resq.software"]
graph TD
subgraph App["src/app/"]
Pages["[locale]/(marketing)/*"]
API["api/[[...route]]"]
end
subgraph Features["src/features/"]
Sections["marketing/sections/"]
Components["marketing/components/"]
end
subgraph Core["Core"]
Hooks["src/hooks/"]
Lib["src/lib/"]
Utils["src/utils/"]
Config["src/config/"]
Actions["src/actions/"]
I18n["src/i18n/"]
end
subgraph Content["content/"]
Posts["posts/*.mdx"]
Changelog["changelog/*.mdx"]
end
Pages --> Sections
Pages --> Components
Sections --> Hooks
Components --> Lib
API --> Elysia["Elysia (health, status)"]
Pages --> Content
| Route | Description |
|---|---|
/[locale] |
Homepage with hero, metrics, problem statement, platform pillars, use cases |
/[locale]/platform |
Platform overview |
/[locale]/protocol |
Protocol details |
/[locale]/contact |
Contact form (name, email, org, message) |
/[locale]/blog |
Blog listing |
/[locale]/blog/[slug] |
Individual blog posts (MDX) |
/[locale]/changelog |
Product changelog |
/[locale]/legal/* |
Privacy, terms, cookies, data processing, acceptable use, security |
/api/health |
Health check (rewrites: /healthz, /health, /ping) |
/api/status |
Better Stack uptime monitor status |
git clone https://github.com/resq-software/landing.git
cd landing
bun install
bun dev # http://localhost:3000| Command | Description |
|---|---|
bun dev |
Dev server (Turbopack) |
bun build |
Production build |
bun test |
Unit tests (bun:test) |
bun test:coverage |
Unit tests with coverage |
bun cy:open |
Cypress E2E (interactive) |
bun cy:run |
Cypress E2E (headless) |
bun lint |
Biome lint check |
bun format |
Biome auto-format |
bun check |
Biome lint + format |
8 test files, 75 tests covering utilities, hooks, and API handlers.
bun test # run all
bun test:coverage # with coverage report| Test file | Coverage |
|---|---|
src/lib/utils.test.ts |
cn() class merging |
src/utils/helpers.test.ts |
URL, scroll, hash, stringify utilities |
src/utils/logger.test.ts |
Logger class with log levels |
src/utils/seo/meta.test.ts |
Metadata constructors |
src/utils/seo/speculation-schema.test.ts |
Schema.org graph builders |
src/hooks/use-in-view.test.ts |
IntersectionObserver hook |
src/app/api/**/health/handlers.test.ts |
Health check handlers |
src/app/api/**/status/handlers.test.ts |
Better Stack status with fetch mocking |
7 spec files covering navigation, homepage sections, contact form validation, API health, locale switching, legal pages, and SEO meta tags.
bun cy:open # interactive mode
bun cy:run # headless CI modegraph LR
subgraph Cloudflare
Worker["Worker<br/>(Next.js SSR)"]
Assets["Static Assets<br/>(HTML, CSS, JS, fonts)"]
DNS["DNS<br/>resq.software"]
end
subgraph External
Sentry["Sentry<br/>(error tracking)"]
BetterStack["Better Stack<br/>(uptime monitoring)"]
end
DNS --> Worker
Worker --> Assets
Worker --> Sentry
Worker --> BetterStack
- Push to
maintriggers CI (build + test + lint) - CI passes triggers the deploy workflow
- OpenNext builds the Next.js app into a Cloudflare Worker bundle
- Wrangler deploys the worker + static assets to Cloudflare
- Static pages (blog, legal, homepage) are prerendered at build time and served from the assets cache
- Dynamic routes (API) are server-rendered by the Worker
The site uses @opennextjs/cloudflare with static-assets caching — no KV, R2, or D1 bindings required.
| Setting | Value | Why |
|---|---|---|
incrementalCache |
static-assets |
Serves prerendered pages from static assets |
queue |
direct |
No ISR revalidation needed |
enableCacheInterception |
false |
Reduces cold start overhead |
| Variable | Required | Description |
|---|---|---|
NEXT_PUBLIC_APP_URL |
No | Canonical site URL |
NEXT_PUBLIC_SENTRY_DSN |
No | Sentry DSN for client-side error tracking |
SENTRY_AUTH_TOKEN |
No | Sentry auth token for source map uploads |
SENTRY_ORG |
No | Sentry organization slug |
SENTRY_PROJECT |
No | Sentry project slug |
BETTERSTACK_API_KEY |
No | Better Stack API key for uptime status |
| Secret | Description |
|---|---|
CLOUDFLARE_API_TOKEN |
Cloudflare API token with Workers Scripts Edit permission |
CLOUDFLARE_ACCOUNT_ID |
Cloudflare account ID |
MDX files in content/posts/ with frontmatter:
---
title: "Post Title"
date: "2026-01-15"
excerpt: "Short description"
tag: "Engineering"
tags: ["mesh", "protocols"]
author: "mike"
readTime: "8 min read"
---MDX files in content/changelog/ with dated entries.
| Layer | Technology |
|---|---|
| Framework | Next.js 16 (App Router, React 19) |
| Styling | Tailwind CSS v4 |
| Language | TypeScript 6 (strict) |
| Runtime | Bun |
| API | Elysia |
| i18n | next-intl (5 locales, RTL support) |
| Forms | TanStack Form + next-safe-action + Zod |
| UI Components | Radix UI + class-variance-authority |
| Linting | Biome |
| Unit Testing | bun:test |
| E2E Testing | Cypress |
| Hosting | Cloudflare Workers (via @opennextjs/cloudflare) |
| Error Tracking | Sentry |
| Uptime | Better Stack |
- Fork and create a branch (
feat/,fix/,docs/) - Run
bun checkbefore committing - Follow Conventional Commits
- Submit a PR against
main— CI must pass