Frontend Architecture
Relevant source files
The following files were used as context for generating this wiki page:
The frontend of WhereIsLifeCheaper is a modern Single Page Application (SPA) built using React 19 and Vite. Its primary purpose is to provide a user-friendly dashboard for comparing grocery prices across multiple countries, visualizing price trends, and offering administrative tools for data management such as product mapping and scraper monitoring.
The architecture emphasizes performance through asynchronous data fetching with TanStack Query and a responsive, utility-first UI powered by Tailwind CSS. It supports internationalization (i18n) and implements robust Search Engine Optimization (SEO) strategies to ensure visibility across different regions and languages.
Sources: frontend/package.json:1-35, plan.md:1-20, README.md:1-25
Tech Stack and Dependencies
The frontend utilizes a modern TypeScript-based stack. Key libraries manage state, routing, and styling.
| Category | Technology | Purpose |
|---|---|---|
| Framework | React 19 | Component-based UI library |
| Build Tool | Vite | Fast development server and bundling |
| Routing | React Router DOM v7 | Client-side navigation and URL management |
| Data Fetching | TanStack Query v5 | Server state management, caching, and synchronization |
| Styling | Tailwind CSS | Utility-first CSS framework for responsive design |
| Icons | Lucide React | Consistent vector icon library |
| i18n | i18next / React-i18next | Multi-language support and locale detection |
| Analytics | PostHog JS | User behavior tracking and pageview capture |
Sources: frontend/package.json:11-30, frontend/src/App.tsx:1-15
Core Component Structure
The application is structured around a central Layout component that wraps the main content area, providing a consistent navigation experience.
Routing and Layout
Navigation is handled by react-router-dom, with the App component defining the route hierarchy. The Layout component includes a Header and a compact Footer, utilizing the <Outlet /> component to render specific page content.
The diagram shows the hierarchical structure from the root App component down to specific page routes.
Sources: frontend/src/App.tsx:37-75, frontend/src/components/layout/Layout.tsx:16-45
Administrative Modules
The application includes specialized pages for administrators to maintain the data integrity of the system:
- Product Mapping: Interface for linking local supermarket products to canonical product identifiers.
- Canonical Freshness: A monitoring dashboard that tracks how recently prices were updated for mapped products, highlighting "stale" data that exceeds a defined threshold (default 7 days).
- Scraper Management: Interface to trigger and monitor the status of various supermarket scrapers.
Sources: frontend/src/App.tsx:55-75, frontend/src/pages/admin/CanonicalFreshness.tsx:40-60
Data Flow and State Management
The frontend maintains a clear separation between local UI state and server-side data.
Server State with TanStack Query
Most data fetching (countries, products, prices) is managed by TanStack Query. This provides automatic caching and background revalidation. For example, the CanonicalFreshness page uses a query key including search terms and pagination state to fetch data through the canonicalApi.
This sequence demonstrates how the frontend handles data requests using TanStack Query to manage the lifecycle of an API call.
Sources: frontend/src/App.tsx:28-35, frontend/src/pages/admin/CanonicalFreshness.tsx:54-65
Localization and SEO
- i18next: The application uses
react-i18nextfor translations. TheLayoutcomponent dynamically updates the HTMLlangattribute whenever the user changes their preferred language. - SEO Hook (
useSEO): A custom hook manages document metadata. It handles the dynamic setting of page titles, meta descriptions, Open Graph (OG) tags, and Twitter cards. It also generates JSON-LD structured data forWebSite,WebPage,BreadcrumbList, andFAQPageschemas.
Sources: frontend/src/hooks/useSEO.ts:18-120, frontend/src/components/layout/Layout.tsx:11-14
UI and Styling
Tailwind Configuration
The project uses a custom Tailwind CSS configuration with a warm, earth-toned color palette, including "terracotta," "olive," "saffron," and "cream." It also defines custom animations like float, glow, and slide-up.
// Example Palette from tailwind.config.js
terracotta: {
50: '#fef7f4',
500: '#e4714a', // Primary brand color
900: '#6f3526',
},
Sources: frontend/tailwind.config.js:21-45
Design Patterns
- Responsive Tables: Used extensively in admin views (e.g.,
CanonicalFreshness.tsx) to display large datasets with pagination controls. - Visual Indicators: The UI uses color-coded rows (e.g., amber for stale data, red for never-scanned data) and Lucide icons to provide immediate feedback to administrators.
Sources: frontend/src/pages/admin/CanonicalFreshness.tsx:135-155, frontend/src/components/layout/Layout.tsx:35-50
Summary
The frontend architecture of WhereIsLifeCheaper is designed to be a lightweight but powerful interface for a complex data-scraping backend. By leveraging React 19 and TanStack Query, the application ensures that the potentially large datasets of grocery prices remain performant and easy to navigate. The inclusion of dedicated admin tools and a robust SEO/i18n strategy makes the platform scalable for global cost-of-living comparisons.