DEV Community

jayanti-neu
jayanti-neu

Posted on

🚛 Freight Tracker: What I Did After Polishing the UI

After finally making all the pages in the Freight Tracker frontend look more polished — with a cleaner layout, better navigation, nicer styling, and a responsive design — I thought I was done. But I wasn't. There was still a lot to improve under the hood.

Here's a breakdown of everything I worked on after the UI was "done," and what I learned along the way:

🔄 Making the App Feel More Dynamic with Zustand and WebSockets

I had already integrated Zustand in Phase 2, but now I made it more useful. Instead of hitting the API every time, I could cache and reuse shipments in the Zustand store. That made the app snappier.

Then I added WebSocket support to make live updates possible — so if a shipment gets updated in real-time (e.g., status changes to "DELIVERED"), it reflects instantly in the UI without the user refreshing the page. This gave the app a much more modern feel.

What I learned:

  • Zustand is great for global state without the boilerplate of Redux
  • useShipmentStore.getState() gives access outside components
  • WebSockets with STOMP and SockJS were already set up in the backend, so I just needed to connect and subscribe to the right topic
  • Having WebSockets + Zustand together means my data stays fresh and fast

🗺️ Making the Map More Realistic

The Map Dashboard looked okay, but loading was slow. Why? Because I was calling the Google Geocode API for every city — every time.

So I added a geocode cache using localStorage. Now if a city was already looked up before, we reuse the coordinates. This made route rendering way faster.

I also:

  • Gave each route a different color based on shipment status
  • Added loading indicators while geocoding
  • Made the map update live when new shipments are added via WebSocket

⚠️ Fixing the Refresh Issue on Netlify

One of the most annoying bugs I ran into: when I refreshed a route like /shipments/2, I got a "page not found" error. Turns out this is a common issue with React apps deployed on Netlify.

The fix? A simple _redirects file in the public/ folder:

/* /index.html 200
That tells Netlify to send all routes to index.html so React Router can do its thing.

🕒 Preventing Backend Sleep with GitHub Actions

After deploying the backend to Render, I noticed that the free tier web service would go to sleep after a few minutes of inactivity. This meant that every time I revisited the app after a while, the backend had to "wake up," causing slow response times or even temporary unavailability.

To fix this, I added a lightweight GitHub Actions workflow in my backend repository that pings the backend url every 10 minutes — just enough to keep it alive without overwhelming it.

Here's what the workflow looks like:


yaml
# .github/workflows/keep-alive.yml
name: Keep Render Backend Alive

on:
  schedule:
    - cron: '*/10 * * * *'  # runs every 10 minutes
  workflow_dispatch:        # allows manual triggering

jobs:
  ping:
    runs-on: ubuntu-latest
    steps:
      - name: Curl the backend
        run: curl --s https://freight-tracker.onrender.com/api/shipments

Once pushed to the main branch, it showed up in the Actions tab on GitHub. Now I never have to worry about the backend sleeping on me. 🚀
⚠️ Note: GitHub Actions schedules are “best-effort” and may not always run exactly on time. If you want a more consistent keep-alive mechanism, consider using a free external ping service like UptimeRobot
 or cron-job.org


## 🌍 Frontend + Backend Deployment

The frontend was deployed on **Netlify** and the backend (Spring Boot) was containerized and deployed on **Render** using Docker.



Key steps I learned:
* Backend needs CORS configured correctly (e.g. allow frontend URL)
* Set up a PostgreSQL DB on Render and connect via environment variables
* Render's default `.mvnw` build failed, so I switched to Docker and wrote a `Dockerfile` instead
* Frontend needed environment variable for backend API (`VITE_API_URL`)
* I had to commit my real `application.properties`, not `application.properties.example`, with placeholders like `${DB_URL}` — and set those secrets in Render





Here's the live app: https://freighttracker.netlify.app/
Enter fullscreen mode Exit fullscreen mode

Top comments (0)