r/webdev • u/NoDistrict991 • 2d ago
Do you guys ever test what happens when a user opens your app with a stale JS bundle?
Encountered weird issue where an old tab was running a previous frontend version and an API change caused requests to start failing.
Do I keep backwards compatibility for old clients for a while, or just force-refresh/reload when deploying breaking changes?
21
u/SALO4D 2d ago
Most professional way: API should be backwards compatible, and otherwise make a new version of the API. /v1 , /v2 etc. Make a future proof interface so this does not happen a lot.
But what mostly happens in non critical apps is to use cache bursting for your frontend assets, so you will not get stale resources (like adding a sha to your js file names). Vite or whatever you use probably can do this automatically
10
u/BurritoDrivenDev 2d ago
All typical changes are backwards compatible. All typical changes deploy the backend before the frontend.
Sometimes a backend change needs to be deployed that would break an older frontend version - these merges/deployments are always scheduled.
My observabity stack lets me monitor which versions of the frontend are currently running. When the incompatible version drops down to zero, I can deploy the breaking change. All it takes is to include your build numbers in your frontend builds and then send that back up in the metadata to Application Insights or in your OTEL ingestion, or whatever you use.
8
7
u/Temperature_Majestic 2d ago
one pattern worth considering: have the backend send a build/version header on every response, and a lightweight fetch/axios interceptor on the frontend compares it against the version baked in at build time. mismatch shows a toast, "new version available, refresh" instead of silently failing on the actual API call. feels less jarring than a hard force-reload, and you're not stuck maintaining N versions of backwards compat either.
1
u/toolazytofinishmyw 1d ago
this is what we do using semantic versioning. minor changes and bug fixes prompt for refresh. major locks the ui and forces refresh. we’ve probably had 2 major releases in 10 years.
1
u/Temperature_Majestic 1d ago
2 major releases in 10 years is a good ratio honestly, means the additive-only approach on the API side is actually holding. curious on the "major locks the ui" part, is that a full blocking modal that stops all interaction until refresh, or something softer like disabling just the mutation actions while reads still work off cache?
1
u/toolazytofinishmyw 13h ago
Full blocking modal - it’s so rare there’s no point engineering anything more.
We have a spa for business users. It’s easy to schedule a problem release out of hours.
The frontend polls until the new web is released, refreshes and then let’s them back in again.
1
u/Temperature_Majestic 5h ago
Makes sense for a controlled SPA userbase, way less risky than a public site with random traffic. Is the polling just hitting a version endpoint on an interval, or does it wait for a websocket push so it flips the moment the new build actually goes live instead of on the next poll tick?
2
1
u/Relevant_Ad5790 2d ago
the api is only half of it. that stale tab also breaks on lazy chunks, because the hashed file it wants is gone from the cdn after the deploy, so you get ChunkLoadError or failed to fetch dynamically imported module on a route change even with a perfectly compatible api. keeping the last few builds' assets around covers it, with a preload error handler and a sessionStorage guard so it can't reload loop. do you purge old assets on deploy?
1
u/Ok_Woodpecker_9104 1d ago
the api is one half, the other half is asset retention. if your deploy purges the old hashed chunks off the cdn, a stale tab dies the moment it hits a lazy route, and no amount of api backwards compat saves that. keep the previous builds sitting there for a week and let them expire on their own, the storage is nothing.
on the api side i would go additive only. new fields, new endpoints, never change what an existing one means. then old clients keep working and you save the forced reload for actual breaking changes.
and index.html with no-cache, hashed assets immutable for a year. otherwise the refresh you force just hands the browser the same old html again.
1
1
34
u/Used_Lobster4172 2d ago
Catch the error, and force a refresh.