Appearance
Marketing Site Overview
The Jubiloop marketing site is a Next.js 15 application serving as the public-facing website for the platform.
Technology Stack
- Framework: Next.js 15 with App Router
- Language: TypeScript
- Styling: Tailwind CSS
- UI Components: shadcn/ui
- CMS: Sanity (for blog content)
- Animations: Framer Motion
- Deployment: Cloudflare Pages
Architecture Overview
Core Concepts
App Router Structure
- File-based routing with RSC support
- Route groups for organization
- Metadata API for SEO
Server Components
- Default to server components
- Client components only when needed
- Optimized bundle size
Static Generation
- All pages statically generated
- Excellent performance
- SEO optimized
Project Structure
src/
├── app/ # App Router pages
│ ├── (main)/ # Main layout group
│ │ ├── contact/ # Contact page
│ │ ├── demo/ # Demo request
│ │ ├── faq/ # FAQ page
│ │ ├── newsletter/ # Newsletter signup
│ │ ├── page.tsx # Homepage
│ │ └── layout.tsx # Shared layout
│ ├── early-access/ # Standalone page
│ │ └── page.tsx
│ ├── layout.tsx # Root layout
│ └── globals.css # Global styles
├── components/
│ ├── animations/ # Interactive demos
│ ├── sections/ # Page sections
│ └── ui/ # shadcn/ui components
└── lib/
└── utils.ts # Utility functionsKey Features
Blog System
- Sanity CMS integration for content management
- Server-side pagination and search
- Author profiles and category filtering
- Responsive grid layouts and loading states
Homepage Components
Hero Section
- Value proposition
- Primary CTA
- Background animations
Features Section
- Interactive feature demos
- Animated on scroll
- Responsive grid layout
Event Types
- Supported event categories
- Visual cards
- Use case examples
Interactive Animations
Located in src/components/animations/:
- AI suggestions demo
- Drag & drop visualization
- Collaboration preview
- Vendor search animation
Early Access Page
Standalone landing page with:
- Unique layout (no nav/footer)
- Signup form with validation
- Confetti celebration effect
- Vision statement
Documentation: Early Access Feature
Development Workflow
Available Scripts
bash
pnpm run dev # Start dev server
pnpm run build # Build for production
pnpm run start # Start production server
pnpm run lint # Run ESLint
pnpm run format # Format with PrettierEnvironment Variables
Required variables in .env.local:
bash
NEXT_PUBLIC_API_URL=http://localhost:3333
NEXT_PUBLIC_APP_URL=http://localhost:5173
NEXT_PUBLIC_APP_ENV=localFeature Flags:
bash
# Early Access Redirects
ENABLE_GLOBAL_REDIRECTS=true
# Analytics (optional)
NEXT_PUBLIC_ENABLE_ANALYTICS=true
NEXT_PUBLIC_ANALYTICS_ID=your_analytics_id
NEXT_PUBLIC_GTM_ID=your_gtm_idSEO & Performance
Metadata API
Each page uses Next.js Metadata API:
typescript
export const metadata: Metadata = {
title: 'Jubiloop - Event Planning Made Simple',
description: 'Collaborative event planning platform',
}Image Optimization
- Next.js Image component for automatic optimization
- Proper alt texts for accessibility
- Lazy loading by default
Performance Features
- Static generation for all pages
- Automatic code splitting
- Font optimization
- CSS optimization
Deployment
The marketing site deploys to Cloudflare Pages:
Build Process
- Next.js static export
- Optimized for edge runtime
- Environment variables injected
Deployment
- Automatic on push to branches
- Preview deployments for PRs
- Separate projects per environment
Common Tasks
Adding a New Page
- Create directory in
app/(main)/ - Add
page.tsxwith metadata - Update navigation if needed
Creating Animations
- Add component to
components/animations/ - Use Framer Motion for effects
- Ensure performance on mobile
Updating Content
Most content is in the page components:
- Homepage:
app/(main)/page.tsx - FAQ:
app/(main)/faq/page.tsx - Contact:
app/(main)/contact/page.tsx
API Integration
The marketing site uses Tuyau (@tuyau/react-query) for type-safe API calls — the same pattern as the webapp. Health checks and newsletter subscription use Tuyau's queryOptions() and mutationOptions().
typescript
// src/lib/api/tuyau.ts
import { createTuyau } from '@tuyau/core/client'
import { createTuyauReactQueryClient } from '@tuyau/react-query'
import { registry } from 'server/registry'
export const tuyau = createTuyau({
baseUrl: process.env.NEXT_PUBLIC_API_URL,
registry,
credentials: 'include',
})
export const api = createTuyauReactQueryClient({ client: tuyau })
// Usage in components
const health = useQuery({ ...api.healthCheck.queryOptions({}), refetchInterval: 30_000 })
const subscribe = useMutation(api.subscriptions.subscribe.mutationOptions())Key characteristics:
- Tuyau for API calls: Type-safe, auto-generated from server routes and validators
- No auth client needed: Public-only content, no session management
- Server components: Can make API calls during SSR/SSG when needed
@jubiloop/logger— Structured logging with adaptor pattern
Best Practices
Performance First
- Minimize client components
- Optimize images and fonts
- Monitor bundle size
SEO Optimization
- Use semantic HTML
- Add proper metadata
- Implement structured data
Accessibility
- ARIA labels where needed
- Keyboard navigation
- Color contrast compliance
Responsive Design
- Mobile-first approach
- Test on various devices
- Use Tailwind breakpoints
Future Enhancements
- Analytics integration (GA4/Plausible)
- A/B testing framework
- Blog/content system
- Internationalization
- Email service integration