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)