Files
Darkraise 9c85284798 fix(settings): show the real web app version
The card always displayed 1.0.0. VITE_APP_VERSION was never set: CI
passes the release tag as a VERSION build arg, but the Dockerfile never
declared it or forwarded it to the frontend build, so the hardcoded
fallback always won.

Declare the build arg and export it as VITE_APP_VERSION, and resolve the
version in vite.config.ts for every other build: the env var, then the
release tag via git describe, then package.json. The image version label
was pinned at 1.0.0 for the same reason and now follows the arg too.
2026-08-12 21:32:49 +07:00

5.9 KiB

Frontend Documentation

Modern React 18 single-page application (SPA) built with TypeScript, Vite, and optimized libraries.

Tech Stack

  • Framework: React 18.3 with TypeScript 5.4
  • Build Tool: Vite 5.2
  • Routing: React Router 6.22
  • State Management:
    • TanStack Query v5.28 for server state
    • Zustand 4.5 for UI state
  • Styling: Tailwind CSS 3.4
  • UI Components: Shadcn UI (40+ components)
  • Icons: Lucide React 0.358
  • Form Handling: React Hook Form 7.71
  • Game Emulation: Ruffle (Flash emulator)

Documentation Structure

Core Documentation

Components

State Management

Player Implementation

Quick Start

Development Server

cd frontend
npm run dev

Starts at http://localhost:5173 with hot module replacement (HMR).

Building for Production

npm run build

Outputs to dist/ directory.

Preview Production Build

npm run preview

Type Checking

npm run typecheck

Key Features

Server State Management

All server data (games, playlists, user data) managed through TanStack Query:

  • Automatic background refetching
  • Optimistic updates
  • Request deduplication
  • Stale-while-revalidate patterns

UI State Management

Client-side UI state (sidebar, theme, auth) uses Zustand stores with localStorage persistence:

  • Minimal boilerplate
  • TypeScript-first
  • DevTools support
  • Middleware for persistence

Type Safety

Fully typed with TypeScript:

  • Strict mode enabled
  • No implicit any
  • Comprehensive type definitions for API responses
  • Type-safe form handling

Performance Optimizations

  • Code splitting at route level
  • Lazy loading for images and components
  • Virtual scrolling for large game lists
  • Memoization for expensive computations
  • Request deduplication and caching

Accessibility

  • ARIA labels on all interactive elements
  • Keyboard navigation support
  • Focus management
  • Screen reader announcements

Environment Variables

The frontend does not require environment variables for local development. API calls are automatically proxied through Vite to the backend.

Optional (production builds):

VITE_APP_VERSION=1.0.38  # Displayed app version

vite.config.ts resolves the version at build time: VITE_APP_VERSION if set, otherwise the release tag via git describe, otherwise package.json. Set it explicitly only where neither is available — the Docker image carries no .git, so CI passes the tag in through the VERSION build arg. Read it in components from @/lib/version, never from import.meta.env directly.

Project Structure

frontend/
├── src/
│   ├── components/        # Reusable UI components
│   │   ├── auth/         # Authentication components
│   │   ├── game/         # Game components
│   │   ├── layout/       # Layout components
│   │   ├── player/       # Game player components
│   │   └── ui/           # Shadcn UI components
│   ├── hooks/            # Custom React hooks
│   ├── lib/              # API client and utilities
│   ├── store/            # Zustand stores
│   ├── types/            # TypeScript types
│   ├── views/            # Page components
│   ├── App.tsx           # Root component with routing
│   └── main.tsx          # Entry point
├── public/               # Static assets
│   └── ruffle/          # Ruffle emulator files
└── index.html           # HTML entry point

Vite Configuration

Dev server proxies both API and game content to backend:

server: {
  proxy: {
    '/api': 'http://localhost:3100',
    '/game-proxy': 'http://localhost:3100',
    '/game-zip': 'http://localhost:3100'
  }
}

In production, Nginx proxies all requests to the backend container.

Common Commands

npm install              # Install dependencies
npm run dev             # Development server with HMR
npm run build           # Production build
npm run preview         # Preview production build
npm run typecheck       # TypeScript type checking
npm run lint            # ESLint code linting