Troubleshooting

Refresh CSS and JavaScript cached by the browser

Reviewed on 3 min read cache navegador

If a deployment changes CSS or JavaScript but keeps the same URL, some browsers may reuse a copy that is still valid. New headers only arrive when the browser requests that URL again: the server can't remotely empty a response the client still considers fresh.

First check in the browser tools' Network tab which URL loads, its status, Cache-Control, Age, ETag, and whether the response comes from the browser, a service worker or a CDN. That way you can tell the HTTP cache apart from other layers.

Change the asset's URL

The reliable fix is to publish each version under a new URL. Ideally, use file names with a hash of the content:

<link rel="stylesheet" href="https://static.example.com/css/app.abc123.css">
<script src="https://static.example.com/js/app.abc123.js"></script>

You can also add a version to the URL, for example /css/app.css?v=20260825, if your application and intermediate caches respect query parameters.

Serve the unversioned HTML with Cache-Control: no-cache so it is revalidated and points to the new assets. no-cache allows storing, but requires validation before reuse. Keep ETag or Last-Modified: they allow a 304 Not Modified response without downloading an identical resource again.

Hashed assets can use a long expiry because their URL changes with the content. If there is a CDN or a service worker, update its manifest too or run that layer's specific purge. Don't keep global no-store rules for weeks, don't remove validators and don't use Pragma as a general substitute for Cache-Control.

See the guide to HTTP caching and versioned URLs and the Cache-Control reference.

Stop a deployment from breaking open sessions

Publish the new files first and then the HTML that references them. Keep the previous version's assets for a transition period: an open tab may still request them. Deleting them straight away can cause 404s even though new visits work.

If the application uses a service worker, test an update with an old tab open alongside a new one. Dynamic or private HTML may need a different policy from public HTML; don't apply a global header without reviewing sessions and sensitive data.

Check the final URL, the content received and the version after the deployment. A 304 response can be correct when the resource hasn't changed; on its own it isn't a sign of a faulty cache.

You may also find useful

Something wrong or out of date? Tell us and we will review it.