A modern, high-performance CTF (Capture The Flag) platform frontend built with Next.js 14, React Query, and Zustand.
- β Landing Page - Beautiful hero section with organization info
- β Authentication - Secure login with JWT/session support
- β Leaderboard - Real-time rankings with auto-refresh
- β User Profile - Comprehensive stats and achievements
- β Challenge System - Category-based challenges with flag submission
- β Responsive Design - Mobile-first, works on all devices
- β State Management - Zustand for client state + React Query for server state
- β Type Safety - Full TypeScript coverage
- β Performance - Optimized with Next.js App Router
- Framework: Next.js 14 (App Router)
- Language: TypeScript 5
- Styling: Tailwind CSS 3
- Client State: Zustand with persistence
- Server State: React Query (TanStack Query)
- Automatic caching and background refetching
- Optimistic updates
- Request deduplication
- Error handling and retries
- HTTP Client: Axios with interceptors
- Form Handling: React Hook Form
- Validation: Zod schemas
- Node.js 18+
- npm or yarn
- Backend API running
-
Install dependencies
npm install
-
Configure environment
# Copy the example env file copy .env.example .env.local # Edit .env.local and set your backend API URL # NEXT_PUBLIC_API_URL=http://localhost:8000/api
-
Run development server
npm run dev
-
Open browser
http://localhost:3000
src/
βββ app/ # Next.js App Router pages
β βββ page.tsx # Landing page
β βββ login/ # Login page
β βββ profile/ # User profile
β βββ leaderboard/ # Leaderboard
β βββ challenges/ # Challenge browser
β βββ layout.tsx # Root layout
β βββ globals.css # Global styles
β
βββ components/ # React components
β βββ ui/ # Reusable UI components
β β βββ Button.tsx
β β βββ Card.tsx
β β βββ Input.tsx
β β βββ Badge.tsx
β βββ Navbar.tsx # Navigation
β βββ Footer.tsx # Footer
β
βββ store/ # Zustand stores
β βββ useAuthStore.ts # Authentication state
β
βββ lib/ # Utilities and configs
β βββ api.ts # Axios instance + interceptors
β βββ apiEndpoints.ts # API helper functions
β βββ queryClient.tsx # React Query provider
β βββ config.ts # App configuration
β
βββ types/ # TypeScript types
βββ index.ts # Shared types
Zustand (Client State)
- β User authentication state
- β Persisted to localStorage
- β Simple, lightweight (~1KB)
- β No boilerplate, just works
React Query (Server State)
- β Automatic caching (5min default)
- β Background refetching
- β Optimistic UI updates
- β Request deduplication
- β Automatic retries on failure
- β DevTools for debugging
- Centralized axios instance
- Request/response interceptors
- Automatic token injection
- Global error handling
- Type-safe endpoints
- User submits login form
- API call with credentials
- Store user + token in Zustand
- Token auto-attached to all requests
- Protected routes check auth status
- Auto-redirect on 401 errors
- User selects genre
- Load challenges for genre
- Submit flag with optimistic update
- Update cache on success
- Refresh user stats
- Show success/error feedback
# Development
npm run dev # Start dev server
# Production
npm run build # Build for production
npm run start # Start production server
# Linting
npm run lint # Run ESLintYour backend should implement these endpoints:
POST /auth/login- Login with email/passwordPOST /auth/logout- Logout userGET /auth/profile- Get current user
GET /genres- List all challenge categoriesGET /challenges/:genreId- Get challenges by genrePOST /submit-flag- Submit flag for validation
GET /leaderboard- Get top players
GET /users/:id- Get user by IDPATCH /users/profile- Update user profile
All components are built with:
- Accessibility in mind
- Mobile-first responsive design
- Consistent design tokens
- Loading states
- Error handling
- Keyboard navigation
// Button with loading state
<Button isLoading={isPending} onClick={handleClick}>
Submit
</Button>
// Input with validation
<Input
label="Email"
error={errors.email?.message}
{...register("email")}
/>
// Card layouts
<Card variant="elevated">
<CardHeader>Title</CardHeader>
<CardBody>Content</CardBody>
</Card>- Next.js App Router - React Server Components
- Code Splitting - Automatic route-based splitting
- Image Optimization - Next.js Image component
- Query Caching - React Query smart caching
- Lazy Loading - Components loaded on demand
- Memoization - Prevent unnecessary re-renders
- Mobile: < 768px
- Tablet: 768px - 1024px
- Desktop: > 1024px
All pages are fully responsive with mobile-first approach.
- β XSS protection via React
- β CSRF tokens (if backend implements)
- β HTTP-only cookies support
- β Secure token storage
- β Auto logout on 401
- β Input validation
# Install testing libraries (not included)
npm install --save-dev @testing-library/react @testing-library/jest-dom jestCreate .env.local:
NEXT_PUBLIC_API_URL=http://localhost:8000/api
NEXT_PUBLIC_APP_NAME="CTF Platform"
NEXT_PUBLIC_APP_URL=http://localhost:3000- Follow the existing code style
- Use TypeScript types
- Write clean, readable code
- Test your changes
- Keep components small and focused
MIT License - feel free to use for your CTF events!
For issues or questions:
- Check the documentation
- Review API responses
- Check browser console
- Verify environment variables
Built with β€οΈ for CTF enthusiasts
This project uses next/font to automatically optimize and load Geist, a new font family for Vercel.
To learn more about Next.js, take a look at the following resources:
- Next.js Documentation - learn about Next.js features and API.
- Learn Next.js - an interactive Next.js tutorial.
You can check out the Next.js GitHub repository - your feedback and contributions are welcome!
The easiest way to deploy your Next.js app is to use the Vercel Platform from the creators of Next.js.
Check out our Next.js deployment documentation for more details.