DEV Community

Kasim kazmi
Kasim kazmi

Posted on

# πŸ› οΈ Built FranΓ§ais Pro: A Technical Deep Dive into Modern French Learning

When your friend needs a solution, you don't just recommend tools - you build them.

My friend's Canadian PR timeline was tight. Existing French learning platforms were either expensive or poorly architected. So I did what any dev would do: built a better one from scratch.

⚑ The Technical Challenge

Create a production-ready French learning platform optimized for Canadian immigration with modern web technologies.

The Stack:

Frontend: Next.js 15 + TypeScript + Tailwind CSS
Backend: Firebase (Firestore + Auth)
Deployment: Vercel
Styling: shadcn/ui + Radix UI
Performance: Server Components + Bundle Optimization
Enter fullscreen mode Exit fullscreen mode

Technical Achievements

Performance Optimization:
β€’ 60% bundle size reduction through strategic code splitting
β€’ Server Components for optimal hydration
β€’ 95+ Lighthouse scores across all metrics
β€’ Sub-2s initial page load

Architecture Decisions:
β€’ React Server Components for SEO-critical pages
β€’ Client Components only where interactivity is needed
β€’ Real-time progress sync with Firestore
β€’ Optimistic UI updates for smooth UX

Developer Experience:
β€’ Full TypeScript coverage with strict typing
β€’ Component-based architecture with shadcn/ui
β€’ Reusable UI system with Tailwind CSS
β€’ Accessibility-first design patterns

Interesting Implementation Details

Web Speech API Integration:
Built custom audio controls using the Web Speech API for pronunciation practice. Users can click any French text to hear native pronunciation:

const speakText = async () => {
  if ('speechSynthesis' in window) {
    const utterance = new SpeechSynthesisUtterance(text);
    utterance.lang = 'fr-FR';
    utterance.rate = 0.8;
    utterance.pitch = 1;
    utterance.volume = 0.8;
    speechSynthesis.speak(utterance);
  }
};
Enter fullscreen mode Exit fullscreen mode

Progress Tracking System:
Real-time sync between client and Firestore with comprehensive progress tracking:

interface UserStats {
  userId: string;
  totalLessonsCompleted: number;
  totalXP: number;
  currentStreak: number;
  longestStreak: number;
  averageScore: number;
  timeSpent: number;
}
Enter fullscreen mode Exit fullscreen mode

Express Entry Integration:
Built custom calculators for Canadian immigration requirements:

// CLB Calculator for language proficiency
const CLB_CONVERSION = {
  'Reading': {
    0: { clb: 0, level: 'No proficiency', color: 'bg-red-500' },
    181: { clb: 4, level: 'Basic', color: 'bg-orange-500' },
    // ... more thresholds
  }
};
Enter fullscreen mode Exit fullscreen mode

🎯 Core Features & Architecture

Smart Content Delivery:

  • Dynamic lesson routing with Next.js App Router
  • Lazy-loaded components with custom hooks
  • Progressive image loading for lesson illustrations
  • Structured learning modules with XP rewards

Real-time Learning Engine:

  • Firebase Firestore for real-time progress sync
  • Optimistic updates with conflict resolution
  • Custom state management with React Context
  • Offline-first architecture considerations

Performance Patterns:

// Server Component for SEO + Client Component for interactivity
export default async function LessonPage({ params }) {
  const lesson = await fetchLesson(params.id); // Server-side
  return <InteractiveLessonClient initialData={lesson} />;
}
Enter fullscreen mode Exit fullscreen mode

πŸ”₯ Technical Highlights

Bundle Optimization:

  • Dynamic imports for lesson components: React.lazy(() => import('./AudioLesson'))
  • Tree-shaking Tailwind with custom config
  • Next.js 15 Turbopack for faster builds
  • Critical CSS extraction for above-the-fold content

Audio Engineering:

  • Web Speech API for pronunciation practice
  • Custom audio button component with loading states
  • Error handling for unsupported browsers
  • Mobile-optimized audio controls

Developer Experience:

# One command setup
npm install && npm run dev
# Type-safe development with TypeScript
npm run type-check
Enter fullscreen mode Exit fullscreen mode

πŸŽ“ Learning Features

Structured Curriculum:

  • 13 learning modules covering foundations to advanced
  • XP reward system (50-150 XP per lesson)
  • Progress tracking with streaks
  • Difficulty-based lesson categorization

Interactive Elements:

  • Click-to-hear pronunciation for any French text
  • Real-time progress visualization
  • Module completion tracking
  • Responsive design for all devices

Immigration Focus:

  • Express Entry CRS score calculator
  • CLB (Canadian Language Benchmarks) calculator
  • Immigration-specific vocabulary
  • Test preparation resources

πŸš€ Why This Matters for Devs

This isn't just another CRUD app. It's a production-ready example of:

  • Modern React patterns in real-world application
  • Performance optimization techniques that actually work
  • Accessibility implementation beyond basic compliance
  • Clean architecture that scales
  • Real-world Firebase integration patterns

Key Learning Points:

  • Server Components vs Client Components strategy
  • Web Speech API integration patterns
  • Firebase real-time data synchronization
  • TypeScript interfaces for complex data structures
  • Component composition with shadcn/ui

Project Structure & Architecture

Next.js 15 App Router Architecture

src/
β”œβ”€β”€ app/                          # Next.js App Router (File-based routing)
β”‚   β”œβ”€β”€ (auth)/                   # Route groups for authentication
β”‚   β”œβ”€β”€ admin/                    # Admin dashboard routes
β”‚   β”œβ”€β”€ learn/[moduleId]/[lessonId]/ # Dynamic learning routes
β”‚   β”œβ”€β”€ layout.tsx               # Root layout with providers
β”‚   β”œβ”€β”€ page.tsx                 # Home page
β”‚   β”œβ”€β”€ globals.css              # Global styles
β”‚   β”œβ”€β”€ manifest.ts              # PWA manifest
β”‚   β”œβ”€β”€ robots.ts                # SEO robots.txt
β”‚   └── sitemap.ts               # Dynamic sitemap generation
β”œβ”€β”€ components/                   # Component library
β”‚   β”œβ”€β”€ ui/                      # shadcn/ui components
β”‚   β”‚   β”œβ”€β”€ audio-button.tsx     # Web Speech API integration
β”‚   β”‚   β”œβ”€β”€ auth-modal.tsx       # Authentication modals
β”‚   β”‚   β”œβ”€β”€ enhanced-button.tsx  # Custom button variants
β”‚   β”‚   └── ...                  # 20+ reusable UI components
β”‚   β”œβ”€β”€ calculators/             # Immigration calculators
β”‚   β”‚   β”œβ”€β”€ clb-calculator.tsx   # Canadian Language Benchmarks
β”‚   β”‚   └── express-entry-calculator.tsx # CRS score calculator
β”‚   β”œβ”€β”€ content/                 # Page-specific content components
β”‚   β”‚   β”œβ”€β”€ alphabet-content.tsx
β”‚   β”‚   β”œβ”€β”€ grammar-content.tsx
β”‚   β”‚   └── ...                  # 15+ content modules
β”‚   β”œβ”€β”€ layout/                  # Layout components
β”‚   β”‚   β”œβ”€β”€ header.tsx           # Navigation header
β”‚   β”‚   β”œβ”€β”€ main-layout.tsx      # Three-column layout
β”‚   β”‚   └── admin-layout.tsx     # Admin dashboard layout
β”‚   └── shared/                  # Shared interactive components
β”œβ”€β”€ contexts/                     # React Context providers
β”‚   β”œβ”€β”€ AuthContext.tsx          # Authentication state management
β”‚   β”œβ”€β”€ FavoritesContext.tsx     # User favorites management
β”‚   β”œβ”€β”€ AdminContext.tsx         # Admin panel state
β”‚   └── search-context.tsx       # Global search state
β”œβ”€β”€ data/                        # Static content & JSON data
β”‚   β”œβ”€β”€ learning-content.ts      # Structured lesson data
β”‚   β”œβ”€β”€ alphabet.json           # French alphabet data
β”‚   β”œβ”€β”€ grammar.json            # Grammar rules & examples
β”‚   β”œβ”€β”€ vocabulary.json         # Vocabulary lists
β”‚   └── ...                     # 15+ JSON content files
β”œβ”€β”€ hooks/                       # Custom React hooks
β”‚   β”œβ”€β”€ useProgress.ts          # Progress tracking hook
β”‚   └── useLoadingState.ts      # Loading state management
β”œβ”€β”€ lib/                        # Utility libraries
β”‚   β”œβ”€β”€ firebase/               # Firebase configuration
β”‚   β”‚   β”œβ”€β”€ config.ts           # Firebase initialization
β”‚   β”‚   β”œβ”€β”€ auth.ts             # Authentication functions
β”‚   β”‚   β”œβ”€β”€ progress.ts         # Progress tracking functions
β”‚   β”‚   └── ...                 # 8+ Firebase modules
β”‚   └── utils/                  # Utility functions
└── types/                      # TypeScript definitions
    β”œβ”€β”€ index.ts                # Main type definitions
    └── data-types.ts           # Data structure types
Enter fullscreen mode Exit fullscreen mode

🎨 Design System & Architecture Patterns

1. Component Architecture:

  • Atomic Design: UI components follow atomic design principles
  • Compound Components: Complex components like modals use compound patterns
  • Render Props: Flexible components that accept render functions
  • Custom Hooks: Business logic separated into reusable hooks

2. State Management Strategy:

// Context-based state management with custom hooks
const AuthContext = createContext<AuthContextType | undefined>(undefined);

// Custom hook for type-safe context usage
export function useAuth() {
  const ctx = useContext(AuthContext);
  if (!ctx) throw new Error('useAuth must be used within an AuthProvider');
  return ctx;
}
Enter fullscreen mode Exit fullscreen mode

3. Layout Architecture:

  • Three-Column Layout: Left sidebar (navigation) + Main content + Right sidebar (quick access)
  • Responsive Design: Mobile-first approach with breakpoint-specific layouts
  • Sticky Navigation: Fixed header with smooth scrolling
  • Progressive Enhancement: Works without JavaScript, enhanced with it

4. Data Flow Architecture:

User Action β†’ Custom Hook β†’ Firebase Service β†’ Context Update β†’ UI Re-render
     ↓              ↓              ↓              ↓
  Component β†’ useProgress β†’ progress.ts β†’ AuthContext β†’ Real-time UI
Enter fullscreen mode Exit fullscreen mode

πŸ”§ Technical Implementation Patterns

1. Server/Client Component Strategy:

// Server Component for SEO-critical pages
export default async function LessonPage({ params }) {
  const lesson = await fetchLesson(params.id); // Server-side data fetching
  return <InteractiveLessonClient initialData={lesson} />; // Client component
}
Enter fullscreen mode Exit fullscreen mode

2. Custom Hook Pattern:

// Progress tracking with real-time updates
export function useProgress() {
  const { user, isAuthenticated } = useAuth();
  const [progress, setProgress] = useState<UserProgress | null>(null);

  // Real-time Firebase integration
  const loadProgress = useCallback(async () => {
    if (!isAuthenticated || !user) return;
    const userProgress = await getUserProgress(user.uid);
    setProgress(userProgress);
  }, [isAuthenticated, user]);

  return { progress, loading, error, updateLesson };
}
Enter fullscreen mode Exit fullscreen mode

3. Context Provider Composition:

// Nested context providers for different concerns
<AuthProvider>
  <UserStorageProvider>
    <AdminProvider>
      <FavoritesProvider>
        <SearchProvider>
          {children}
        </SearchProvider>
      </FavoritesProvider>
    </AdminProvider>
  </UserStorageProvider>
</AuthProvider>
Enter fullscreen mode Exit fullscreen mode

πŸš€ Performance Architecture

1. Code Splitting Strategy:

  • Route-based splitting: Each page loads only necessary code
  • Component-based splitting: Heavy components loaded on demand
  • Dynamic imports: React.lazy() for non-critical components

2. Bundle Optimization:

  • Tree shaking: Unused code eliminated at build time
  • Turbopack: Next.js 15's fast bundler for development
  • Image optimization: Next.js automatic image optimization

3. Caching Strategy:

  • Static generation: Pre-built pages for better performance
  • ISR (Incremental Static Regeneration): Dynamic content with static benefits
  • Client-side caching: React Query for API response caching

πŸ”’ Security & Authentication Architecture

1. Firebase Authentication:

// Centralized auth state management
interface AuthContextType {
  user: AppUser | null;
  isLoading: boolean;
  login: (email: string, password: string) => Promise<boolean>;
  signup: (name: string, email: string, password: string) => Promise<boolean>;
  loginWithGoogle: () => Promise<boolean>;
  logout: () => void;
  isAuthenticated: boolean;
}
Enter fullscreen mode Exit fullscreen mode

2. Route Protection:

  • AuthGuard component: Protects authenticated routes
  • Role-based access: Admin vs user permissions
  • Client-side validation: Immediate feedback for auth errors

Mobile-First Architecture

1. Responsive Design System:

  • Breakpoint strategy: Mobile-first with progressive enhancement
  • Touch optimization: Mobile-friendly interactions
  • PWA capabilities: Service worker for offline functionality

2. Performance on Mobile:

  • Critical CSS: Above-the-fold styles inlined
  • Lazy loading: Images and components loaded on demand
  • Bundle size: Optimized for slower mobile connections

Live Demo: Frenchpro.ca

Source Code: Open source on GitHub

Question for the community: What's your go-to pattern for handling real-time data in educational apps? Always curious about different approaches to state synchronization!


Building solutions for real problems hits different. Sometimes the best side projects come from helping friends.

Top comments (0)