Case 07 / 17 · Formula 1 data platform · 2026

Apex

A Formula 1 web app styled like a printed Grand Prix programme: full championship stats, driver form, team and circuit history — on live Ergast API data.

https://f1.lkxa.ru

  • Development time: 13 days
  • Routes: 12
  • Archive depth: 1950–2026
  • Bundle size (gzip): ≈122 KB

Challenge

Existing F1 sites are either ad-heavy news feeds with pop-ups or dry tables with no visual hierarchy. What was missing was a product that presents championship data as a coherent publication: with typography, rhythm and sports-media attention to detail.

Solution

A React + Vite SPA with no backend: all data comes straight from the open Ergast API (via the maintained Jolpica mirror) and the Wikipedia REST API. A custom network layer with a request queue, exponential backoff and a two-level cache makes navigation instant and barely touches the API. The design system is built like a Swiss printed programme: a modular grid, rules, dotted leaders, halftone photo plates, tabular figures.

Highlights

React 18 + Vite + React Router 6 · Ergast API + Wikipedia REST · 2 themes, 2 languages · 12 routes, no backend

What was built

  • A “Grand Prix printed programme” design system: a 12-column grid, typographic rules, dotted leaders, numbered sections
  • Two editions: Paper (light) and Night (dark) — a toggle in the header, the choice is remembered, the first visit follows the OS setting
  • Fully bilingual RU/EN: interface, retirement statuses, date formats and localised Wikipedia texts
  • Russian Wikipedia localisation via langlinks: an English article title resolves to the Cyrillic one, redirects included
  • Three plural forms for Russian (“1 победа / 2 победы / 5 побед”)
  • A custom network layer: a queue with limited concurrency (2 requests, 220 ms apart) and backoff on 429/5xx honouring Retry-After
  • A two-level cache (memory + localStorage): live data for 15 minutes, historical stats for 24 hours, deduplication of concurrent requests
  • Paged loading (ergastPaged): the lap chart is ~12 pages fetched in parallel through the queue and cached as one entry
  • A lap-by-lap position chart (“spaghetti”): a line per car in team colours, hovering highlights a driver and dims the rest, pit stops are circled, labels on the right edge are de-collided
  • Points progression charts by race with an interactive hover readout
  • Halftone photo plates: black-and-white with a screen pattern, a duotone in team colour on hover — masks the uneven source photos from Wikipedia
  • A dynamic accent colour: the page takes on the livery of the team in focus (championship leader, selected driver, race winner)
  • A countdown to the next race and the weekend schedule (FP1 to qualifying, sprint if there is one)
  • Race page: finishing order, qualifying, sprint, lap chart, pit stops — in tabs
  • An archive of every season 1950–2026: an index by decade, a season page with a champion feature, final standings and a calendar with winners
  • Circuit pages: stats, description, every winner since 1950, top drivers and teams by wins, every Grand Prix held
  • Driver page: career stats, biography, championship progress against the teammate, a lap-by-lap log of every race of the season
  • Skeletons instead of spinners: placeholders match the shape of the real content, nothing “jumps” while loading
  • Responsive layout: on mobile, navigation and toggles fold into a dropdown panel, wide tables scroll inside their container
  • Framer Motion animations: page transitions, points counters, progress bars, chart lines drawing in — transform/opacity only
  • Plain CSS, no framework: semantic tokens, a single 8pt spacing scale, both editions described as token sets
  • An nginx config for static deployment: SPA fallback, immutable caching of hashed assets, gzip

Stages

  1. Research and design language (2 days) — Studying current directions, choosing the printed-programme aesthetic, a token-based design system, light and dark editions
  2. Network layer (2 days) — Ergast client: request queue, backoff, two-level cache, deduplication, paged assembly of lap data
  3. Core pages (3 days) — Home, drivers, teams, calendar, race results, standings — laid out on the modular grid, with skeletons
  4. Visualisations (2 days) — Lap chart, points charts, halftone plates, countdown, weekend schedule
  5. RU/EN localisation (2 days) — Interface dictionary, retirement statuses, date formats, Russian Wikipedia texts via langlinks, plural forms
  6. Archive and circuits (1 day) — Seasons 1950–2026, season and circuit pages, winners history, cross-linking
  7. Polish and deployment (1 day) — Mobile navigation, chart label de-collision, request optimisation, nginx config

Next project: Sound of the Century