Landing page + waitlist funnel for Signpost — learn ASL with real-time AI computer vision feedback.
- Main site: https://signpost.cv
- Demo: https://demo.signpost.cv
- Next.js 16 (App Router)
- React 19
- TypeScript
- GSAP + ScrollTrigger (animations)
- Neon Serverless Postgres (waitlist data)
- Vercel (hosting)
- Node.js 20+
- npm
- A Neon project with a
waitlisttable
Create .env.local with:
DATABASE_URL=postgresql://<user>:<password>@<host>.neon.tech/<dbname>?sslmode=require- Install dependencies:
npm install- Start Next.js:
npm run devnpm run dev— start local dev servernpm run build— production buildnpm run start— run production servernpm run lint— run ESLint
The waitlist is powered by Neon Serverless Postgres with Next.js API routes:
- Join:
POST /api/waitlist/join→src/app/api/waitlist/join/route.ts - Check status:
POST /api/waitlist/check→src/app/api/waitlist/check/route.ts - DB connection:
src/lib/db.ts - Frontend modal:
src/app/WaitlistModal.tsx
Protections:
- Hidden honeypot field for bot detection
- Email format validation + normalization
- Blocklist for disposable email domains
- Duplicate email protection (
ON CONFLICT DO NOTHING) - In-memory rate limiting
flowchart LR
U[User Browser] --> N[Next.js App]
N --> W[Waitlist Modal]
W --> A[API Routes]
A --> D[(Neon Postgres)]
Key files:
- Landing page:
src/app/page.tsx - Waitlist modal:
src/app/WaitlistModal.tsx - API route (join):
src/app/api/waitlist/join/route.ts - API route (check):
src/app/api/waitlist/check/route.ts - DB connection:
src/lib/db.ts
Security headers are configured in next.config.ts:
Content-Security-PolicyX-Content-Type-OptionsX-Frame-OptionsReferrer-PolicyPermissions-PolicyCross-Origin-Opener-PolicyCross-Origin-Embedder-PolicyCross-Origin-Resource-PolicyX-Permitted-Cross-Domain-PoliciesStrict-Transport-Security(production only)poweredByHeader: false
- Platform: Vercel
- Set
DATABASE_URLin Vercel project environment variables - Ensure the Neon
waitlisttable exists before deploying
- Build may fail in offline environments because
next/font/googlefetches fonts at build time. - If waitlist API routes return 500, verify
DATABASE_URLis set and the Neon project is active.