DEV Community

jayanti-neu
jayanti-neu

Posted on

πŸš€ Building the Freight Tracker Frontend (Phase 1)

In the previous phases, we built the backend API and added real-time updates with WebSockets. Now it's time to bring the frontend to life β€” building a React + TypeScript + Tailwind Single Page Application (SPA) that talks to our backend.

This post covers Phase 1 of the frontend: setting up the project, defining its folder structure, and configuring routing for multiple pages.

🎯 Goals of Phase 1

  • Set up React project with Vite + TypeScript + Tailwind CSS
  • Create a scalable folder structure used in professional projects
  • Implement basic routing (Home + Shipments pages)
  • Understand SPA architecture and why React Router is needed

πŸ›  Tech Stack

  • React (UI library)
  • TypeScript (type safety)
  • Vite (fast dev bundler)
  • Tailwind CSS (utility-first styling)
  • React Router DOM (SPA routing)

1. Project Setup

Create Vite project

npm create vite@latest client-freight
# Choose React + TypeScript
cd client-freight
Enter fullscreen mode Exit fullscreen mode

Install Tailwind (latest)

npm install -D tailwindcss @tailwindcss/vite
Enter fullscreen mode Exit fullscreen mode

Edit vite.config.ts:

import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import tailwindcss from "@tailwindcss/vite";

export default defineConfig({
  plugins: [react(), tailwindcss()],
});
Enter fullscreen mode Exit fullscreen mode

Add Tailwind directives in index.css:

@tailwind base;
@tailwind components;
@tailwind utilities;
Enter fullscreen mode Exit fullscreen mode

Run:

npm run dev
Enter fullscreen mode Exit fullscreen mode

You should see the default Vite React page at http://localhost:5173.

2. Professional Folder Structure

Here's the structure we created under src/:

src/
β”‚
β”œβ”€β”€ components/        # Reusable UI components (buttons, cards, etc.)
β”œβ”€β”€ pages/             # Full-page components (HomePage, ShipmentsPage)
β”œβ”€β”€ hooks/             # Custom React hooks (e.g., useShipments)
β”œβ”€β”€ services/          # API calls / WebSocket helpers
β”œβ”€β”€ types/             # TypeScript types/interfaces
β”œβ”€β”€ context/           # React context (e.g., AuthContext, ThemeContext)
β”œβ”€β”€ App.tsx            # Main app component (routing setup)
β”œβ”€β”€ main.tsx           # Vite entry point
└── index.css          # Tailwind global styles
Enter fullscreen mode Exit fullscreen mode

Why this structure?

  • components/: Small reusable building blocks (e.g., <Button />, <Card />)
  • pages/: Represents real screens/routes (/ for home, /shipments for shipments list)
  • hooks/: Encapsulate logic like data fetching or WebSocket subscriptions
  • services/: All HTTP/WebSocket calls centralized here (e.g., getShipments())
  • types/: Centralized TypeScript interfaces to keep backend and frontend consistent
  • context/: Global state management (e.g., authentication, theme)

This separation scales well as the project grows and keeps responsibilities clear.

3. What is an SPA and Why React Router?

How SPAs Work

A Single Page Application (SPA) loads one HTML page and dynamically updates the content with JavaScript (React) instead of requesting new HTML pages from the server.

  • Faster navigation after first load
  • No full-page refresh β€” feels more like a native app
  • Better user experience for dashboards, real-time apps, etc.

Why React Router DOM?

You could theoretically build a single-view SPA with just React and no router at all. React Router DOM becomes necessary when you want that SPA to feel like it has multiple "pages" that users can navigate between.

Without React Router, you'd have to manually manage window.location and conditional rendering. React Router DOM handles:

  • URL-based navigation (/, /shipments)
  • Back/forward browser buttons
  • Page transitions without reloads
  • Preserving state between page views

But React itself is what makes SPAs possible by:

  • Managing the virtual DOM and efficiently updating only changed parts
  • Creating reusable components that can be dynamically rendered
  • Handling state changes without page reloads
  • Providing the foundation for building interactive UIs

4. Implementing Routing

Install React Router DOM:

npm install react-router-dom
Enter fullscreen mode Exit fullscreen mode

App.tsx

import { BrowserRouter as Router, Routes, Route, Link } from "react-router-dom";
import HomePage from "./pages/HomePage";
import ShipmentsPage from "./pages/ShipmentsPage";

export default function App() {
  return (
    <Router>
      <nav className="p-4 bg-gray-800 text-white flex gap-4">
        <Link to="/">Home</Link>
        <Link to="/shipments">Shipments</Link>
      </nav>

      <Routes>
        <Route path="/" element={<HomePage />} />
        <Route path="/shipments" element={<ShipmentsPage />} />
      </Routes>
    </Router>
  );
}
Enter fullscreen mode Exit fullscreen mode

pages/HomePage.tsx

export default function HomePage() {
  return <h1 className="text-2xl font-bold p-4">Welcome to Freight Tracker</h1>;
}
Enter fullscreen mode Exit fullscreen mode

pages/ShipmentsPage.tsx

export default function ShipmentsPage() {
  return <h1 className="text-2xl font-bold p-4">Shipments</h1>;
}
Enter fullscreen mode Exit fullscreen mode

How Navigation Works

  1. User visits / β†’ Sees nav bar + HomePage
  2. Clicks "Shipments" link β†’ URL changes to /shipments, React swaps HomePage with ShipmentsPage (no reload)
  3. Nav bar stays persistent across all routes

This is what makes SPAs fast and seamless.

5. Key Learnings from Phase 1

  • Tailwind + Vite gives rapid dev speed + modern CSS utilities
  • SPA model: one-page load, client-side routing, smooth navigation
  • React Router DOM: essential for multiple "pages" in SPAs
  • Folder structure: separation of pages, components, services, types keeps things clean

6. What's Next?

  • Phase 2 Frontend: Fetch shipments from backend API
  • Add real-time WebSocket updates
  • Create responsive UI components (cards, tables)
  • Later: auth, filtering, deployment

GitHub Repo

Frontend code is available here: GitHub - freight-tracker-frontend


Top comments (0)