Full-Stack Web Application

CarHub Platform

Hassan Firouzi
AuthorHassan Firouzi
PublishedApril 30, 2026
Length6 min read
CarHub Platform
System_Notice

Executive Summary

CarHub is a React and TypeScript car catalog built with Vite, browsing a real public vehicle dataset through filters and pagination that live entirely in the URL — refresh the page or share the link, and the exact same results come back.

The Problem Space

Before writing any UI, I identified what actually breaks in listing platforms once they leave the tutorial stage:

  • Filter State That Doesn't Survive: Component-state filters vanish on refresh and can't be shared as a link.
  • Mock Data Hides Real Problems: A hardcoded array never forces you to handle a slow, occasionally messy third-party API honestly.
  • Client-Side Pagination Doesn't Scale: Fetching everything up front falls apart against a dataset with thousands of vehicles.

System Architecture

CarHub is a React 19 and TypeScript front end built with Vite. Filter and pagination state live entirely in the URL via React Router's useSearchParams — there's no separate component state duplicating what the URL already holds, so back/forward navigation and shared links just work.

  • URL as the Source of Truth: Make, model, year, and page all read from and write to the query string.
  • Server-Side Pagination: The results grid re-fetches from the API whenever the URL params change, computing limit/offset instead of slicing a full dataset client-side.
  • Real Public Data: Listings come from OpenDataSoft's public vehicle dataset, not a mocked catalog.

Technical Implementation

The project is built on React and TypeScript with Vite, using React Router for URL-synced filter state and the OpenDataSoft public dataset API for real vehicle data. Here's how the core listing fetch works:

Terminal
export const fetchCars = async (
  make: string,
  model: string,
  year: string,
  page: string,
  limit: number,
): Promise<CarResponse> => {
  const base =
    "https://public.opendatasoft.com/api/explore/v2.1/catalog" +
    "/datasets/all-vehicles-model/records";
  let url = `${base}?limit=${limit}`;

  if (make) url += `&refine=make:"${make}"`;
  if (model) url += `&refine=model:"${model}"`;
  if (year) url += `&refine=year:"${year}"`;

  const offset = (Number(page) - 1) * limit;
  url += `&offset=${offset}`;

  const res = await fetch(url);
  return await res.json();
};

Key Features

  • Marka, Model & Year Filters: A searchable make select, free-text model input, and year filter, all synced to the URL on submit.
  • Real Vehicle Data: Every result comes from a live public dataset, not a mocked catalog.
  • Shareable Pagination: Page state lives in the URL and scrolls back to the top of the results on change.
  • Explicit Loading, Empty & Error States: The grid never silently hangs — it shows a loader, a real error message, or an honest empty state.

Impact & Results

  • Filter and pagination state is shareable and survives a refresh by design, not bolted on afterward.
  • Working against a real, occasionally messy public dataset taught me to treat loading and error states as first-class, not edge cases.
  • Reinforced URL-as-state as a pattern I now reach for by default in listing UIs.
Return to index
Authenticated EntryApril 30, 2026

End of Journal Entry