Appearance
Local Dev No Cache
When to use
Use this pattern when you need HTTP requests to bypass the browser cache during local development but use normal caching in production. This avoids stale content during development without requiring manual cache-clearing or hard refreshes, and without penalizing production performance.
The pattern
Detect whether the page is running on localhost. Use that flag to control caching on every outgoing request. No environment variables or build flags are needed — the hostname is the convention.
Detect dev mode
Check the current hostname to determine whether the page is running locally. This single flag drives all cache decisions without build-time configuration:
javascript
const DEVELOPMENT = window.location.hostname === "localhost";This single check covers the common case: local development servers run on localhost, while deployed apps use a real hostname. If your dev server binds to 127.0.0.1 or a custom hostname, extend the check:
javascript
const DEVELOPMENT = ["localhost", "127.0.0.1"].includes(window.location.hostname);Disable cache in dev with jQuery
With jQuery's $.ajax, the cache: false option appends a _={timestamp} query parameter that busts the browser cache. Setting cache: !DEVELOPMENT enables caching in production and disables it on localhost:
javascript
$.ajax({
url: path,
cache: !DEVELOPMENT,
}).success(function (content) {
el.html = content;
});Disable cache in dev with fetch
The Fetch API accepts a cache option directly. Use "no-cache" in dev to force revalidation, and "default" in production to allow normal caching:
javascript
const response = await fetch(url, {
cache: DEVELOPMENT ? "no-cache" : "default",
});Disable cache in dev with Axios
Axios does not natively support the cache option, but you can set Cache-Control headers or append a timestamp query parameter:
javascript
import axios from "axios";
const http = axios.create({
headers: {
"Cache-Control": DEVELOPMENT ? "no-cache" : undefined,
},
});Loading HTML partials
A widget that fetches HTML from the server and injects it into the page. In development, every navigation gets fresh content:
javascript
const DEVELOPMENT = window.location.hostname === "localhost";
async function loadPartial(el) {
const path = el.getAttribute("src");
if (!path) return;
const response = await fetch(path, {
cache: DEVELOPMENT ? "no-cache" : "default",
});
const html = await response.text();
el.innerHTML = html;
}Pre-configured Axios client
A shared HTTP module that automatically disables caching on localhost:
javascript
import axios from "axios";
const DEVELOPMENT = window.location.hostname === "localhost";
export const http = axios.create({
method: "GET",
headers: {
"Accept": "application/json;charset=UTF-8",
...(DEVELOPMENT && {
"Cache-Control": "no-cache",
}),
},
});Trade-offs
Convention over configuration. The pattern relies on the convention that localhost means development. This works for most setups but will not work if the production app also runs on localhost (e.g. Electron apps) or if the dev server uses a custom hostname.
No build step required. Because the check happens at runtime, you do not need environment variables, build flags, or conditional compilation. The trade-off is a small runtime cost for the hostname comparison on every request.
Cache busting is per-request. This approach disables caching at the request level, not globally. If you need to bust the cache for static assets (CSS, images), you will need a different strategy such as filename hashing or service-worker control.