Next.js Quiz App Guide
This skill provides expert guidance for working with a Next.js 15-based interactive quiz application for Latin-Dutch vocabulary learning. The application emphasizes extreme performance optimization and client-side architecture.
Project Characteristics
**Client-side only** (no backend/API routes)**91 Latin vocabulary words** from chapters 8, 9, and 10**Modern UI** with shadcn/ui components and Tailwind CSS**Optimized bundle**: 117KB initial (~30-35KB gzipped)**Performance**: <5ms quiz start time, <2ms answer validationInstructions
1. Understanding the Architecture
Before making any changes:
Review the single-page client component architecture using Next.js 15 App Router**Main orchestrator** is `components/quiz.tsx` (state machine with "not-started" | "in-progress" | "finished" states)**State-specific components** are lazy-loaded with `require()` and wrapped with `React.memo`: - `quiz-start.tsx` - Start screen
- `quiz-question.tsx` - Question display
- `quiz-results.tsx` - Results screen
**Data layer** consists of: - `data/vocabulary.ts` - Single source of truth (VOCAB object with 91 words)
- `lib/quiz-utils.ts` - Quiz logic and utilities
- `types/quiz.ts` - TypeScript definitions
2. Maintaining Performance Optimizations
**CRITICAL**: This codebase is heavily optimized. Always maintain these patterns:
**Data caching**:
Module-level cache in `vocabulary.ts` (cachedVocabularyItems)Map-based cache in `quiz-utils.ts` (translationCache)Never recompute these on each call**React optimizations**:
Use `useMemo` for derived state (currentItem, progress, totalVocabItems)Use `useCallback` for event handlers (startQuiz, handleSubmit, moveToNext)Wrap state-specific components with `React.memo`Use lazy loading with `require()` instead of `next/dynamic`**Bundle optimization**:
Maintain `optimizePackageImports` in `next.config.js`Tree shaking must remain enabledKeep compression enabled for production3. Working with Quiz Logic
**Quiz Flow**:
1. Start: Shuffle vocabulary, initialize state
2. Question Loop:
- Present Latin word
- First wrong answer → Show hint (0.5 points if corrected)
- Second wrong answer → Show correct answer, move next (0 points)
- Correct answer → Award points (1 or 0.5), move next
3. Results: Display score, percentage, grade (1-10), review wrong answers
**Answer Normalization**:
Case-insensitive matchingRemoves optional prefixes like "(be)"Splits on commas and slashes for multiple valid answersWhitespace trimming4. Development Workflow
**Setup and running**:
```bash
npm install # Install dependencies
npm run dev # Start dev server at http://localhost:3000
npm run build # Create production build
npm start # Start production server
npm run lint # Lint code
npm run analyze # Analyze bundle size
npx tsc --noEmit # Type check
```
5. Making Changes
**State management**:
All quiz state lives in `components/quiz.tsx`Don't split into separate stores or context unless absolutely necessaryUse existing useState hooks pattern**Adding features**:
This is purely client-side - don't add API routes unless explicitly requiredAll user-facing text, comments, and variables must be in **Dutch**Maintain the three-state machine pattern (not-started → in-progress → finished)**UI components**:
Use existing shadcn/ui components from `components/ui/`Customize with Tailwind CSSFollow existing design token patterns in `tailwind.config.ts`6. Code Quality Standards
**TypeScript**: Use strict typing, all types defined in `types/quiz.ts`**Language**: All user-facing text, comments, and variable names in **Dutch****Package management**: Use npm (not yarn or pnpm)**No backend**: Keep application purely client-side**Performance first**: Always check impact on bundle size and runtime performance7. Configuration Files
**Next.js Config** (`next.config.js`):
`reactStrictMode: true` for development bug catching`optimizePackageImports` for UI libraries`compress: true` for production`poweredByHeader: false` for security**Tailwind Config** (`tailwind.config.ts`):
shadcn/ui integration with design tokensCustom theme configurationAnimation support via tailwindcss-animate8. Common Tasks
**Adding vocabulary**:
Edit `data/vocabulary.ts`Add to appropriate chapter section in VOCAB objectFormat: `"latin": "dutch translation"`Cache will automatically update on next load**Modifying quiz scoring**:
Edit `lib/quiz-utils.ts`Functions: `calculateGrade()`, `calculatePercentage()`Maintain 1-10 grading scale**Updating UI**:
Edit components in `components/`Use existing shadcn/ui componentsMaintain React.memo wrappers on state-specific components**Bundle analysis**:
```bash
npm run analyze
```
Review impact of changes on bundle sizeTarget: Keep initial bundle under 120KBCompressed target: Under 40KB gzippedImportant Constraints
1. **No test infrastructure** currently exists (add Jest + React Testing Library if needed)
2. **Performance is critical** - review `PERFORMANCE.md` before making changes
3. **Lazy loading pattern** - Use `require()` for state-based component loading
4. **Deployment** - Can deploy to Vercel or any static hosting
5. **Dutch language** - All text must be in Dutch for Dutch-speaking students
Notes
Application uses React 19 and Next.js 15.5+TypeScript 5 strict modeSingle-page application architectureAll optimizations are documented and should be maintained