🧠 Why Your App Only Loads After a Hard Reload (and How to Fix It)

Imagine this: You build a beautiful web app, deploy it, and everything seems fine... until someone visits your site and it doesn’t load. But if they hard refresh (Ctrl + Shift + R
) — suddenly, it works like magic.
Sounds familiar?
This is one of those classic frontend frustrations that feels like a browser bug, but it’s actually tied to caching, service workers, or incorrect routing setups. Let's dig into this and fix it once and for all.
🧩 What's Really Happening?
When your app doesn't load normally, but works on hard reload, it's often due to:
Aggressive caching (from service workers or browsers)
Broken routing in single-page applications
Syntax errors in the manifest file
Missing or misconfigured assets
Let’s break down each of these issues — and how to solve them.
1. 🧹 Service Worker or PWA Caching Problems
If your app uses a service worker (often through a PWA setup), the browser might be serving old, cached files — even if you’ve updated them.
✅ How to Fix It
Unregister the service worker while developing:
Go to DevTools → Application → Service Workers
Click “Unregister”
Add this to your service worker to make it update immediately:
self.addEventListener('install', (event) => { self.skipWaiting(); }); self.addEventListener('activate', (event) => { event.waitUntil(clients.claim()); });
2. 🧭 SPA Routing Issues (React, Vue, etc.)
If you’re using client-side routing with React Router or Vue Router, refreshing works because the app is already loaded. But hitting a URL directly (like /dashboard
) gives a 404 error unless the server knows to fallback to index.html
.
✅ How to Fix It
If you're using Vite, add this to your vite.config.js
:
import { defineConfig } from 'vite';
export default defineConfig({
server: {
historyApiFallback: true,
},
});
For Express:
app.use('*', (req, res) => {
res.sendFile(path.resolve(__dirname, 'dist', 'index.html'));
});
For Nginx:
location / {
try_files $uri /index.html;
}
3. ⚠️ Manifest File Syntax Error
If your browser shows:
Manifest: Line: 1, column: 1, Syntax error.
Your manifest.json
is likely broken or missing. That can silently cause your app not to load, especially in PWAs.
✅ How to Fix It
Make sure
manifest.json
is valid JSON (no trailing commas).Use JSONLint to validate.
Ensure it's linked properly:
<link rel="manifest" href="/manifest.json?v=1">
4. 🧼 Cached Files Aren’t Updating
Sometimes the browser caches your assets too aggressively — and a normal reload doesn’t fetch the new versions.
✅ How to Fix It
Add versioning to static assets:
<link rel="stylesheet" href="/styles.css?v=2" /> <script src="/main.js?v=5"></script>
During development, enable Disable cache in DevTools → Network.
5. 🗂 Incorrect Base Path (for Subdirectory Hosting)
If you're hosting your app in a subfolder (like example.com/app/
), you must set the correct base
in your config.
✅ Fix for Vite
export default defineConfig({
base: '/app/',
});
✅ Final Checklist to Solve This
Before you panic next time your app doesn't load:
✅ Unregister old service workers
✅ Fix your
manifest.json
✅ Enable history fallback for SPA routing
✅ Bust browser cache with versioning
✅ Double-check asset paths and base config
🧪 Bonus: How to Debug It
Use Chrome DevTools to help narrow it down:
Console Tab: Look for red error messages
Network Tab: See if anything failed to load (especially
.js
or.json
)Application Tab: Check if a service worker is registered or if the manifest failed
💬 Conclusion
Having to hard-refresh your app to make it work isn't something you should settle for — it's a fixable problem. Whether it's caching, service workers, or routing issues, now you've got a toolkit to solve it.
If you're still stuck, feel free to drop your manifest or config file — we developers have all been there!
Subscribe to my newsletter
Read articles from Forhad Hossain directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Forhad Hossain
Forhad Hossain
Hi, I'm Farhad Hossain, a passionate web developer on a journey to build impactful software and solve real-world problems. I share coding tips, tutorials, and my growth experiences to inspire others.