All posts

How I Built a Live Weather App (And What Nearly Broke Me)

I thought a weather app would be a quick build. Fetch some data, display it nicely, done. Tutorials make it look that straightforward. The actual build was a different story.

The finished version has live forecasts, hourly breakdowns, a 7-day outlook, sunrise and sunset times, UV index, wind speed, humidity, and city search with auto-suggest. Getting all of it working and looking decent took a lot more work than I'd planned for.

Starting with the API

I used the OpenWeatherMap API, which has a solid free tier. Getting a basic response back was easy enough. Everything after that was where things got interesting.

Real API data has rough edges. Fields you expect are sometimes missing. Temperature comes back in Kelvin by default, which I didn't catch for an embarrassingly long time. Wind direction is in degrees rather than compass points, so I had to write a conversion function to turn 247 into "WSW". UV index lives on a completely separate endpoint. Sunrise and sunset come back as Unix timestamps. None of this is hard to deal with, but none of it is mentioned in any tutorial either.

Tutorials show you the happy path. Real API data has missing fields, weird formats, and edge cases the documentation skips over. Build with that in mind from day one.

The CORS problem

For a while the app worked fine locally and broke completely once it was live. The browser was blocking requests because of CORS restrictions. The fix was straightforward once I found it: switch from HTTP to HTTPS and set the right headers. Getting to that answer took most of an afternoon because the console error wasn't very descriptive and the Stack Overflow answers all pointed in slightly different directions.

Making it look good

Once the data was reliable I spent a good amount of time on the UI. A weather app that just shows you a list of numbers isn't useful. I ended up building:

  • A dynamic background that changes based on weather condition and time of day
  • Custom SVG icons for each weather state
  • A horizontal scroll for the hourly forecast
  • Cards for the 7-day outlook showing min and max temps

The background gradients took the most time. I wanted a deep orange for sunrise, a flat grey for overcast, a dark blue for night. Getting those transitions to look natural without being over the top was harder than it sounds.

The city search

Search runs a geocoding call first to turn a city name into coordinates, then passes those to the weather API. Simple in theory. In practice you need to handle duplicate city names across countries, empty results, users typing quickly and firing off too many requests, and a fallback to the user's current location when search fails.

Adding a debounce to the input so it only fires after 400ms of no typing cut the number of API calls by around 80% on its own. Worth doing on any search input.

What I'd do differently

I'd sort out the data model before touching the UI. I jumped straight into building screens before I properly understood what data I had and in what shape it came. That led to a bunch of refactoring halfway through when something I thought was one API call turned out to need three.

The app is live on the Work tab if you want to try it. Give it your location and it'll pull in the live forecast.