$ curl -sI https://yourapp.com/pricing | head -1Refreshing any page gives 404
The most common single failure in apps built with Lovable, Bolt and Replit — and the one with the shortest fix.
Seen in apps built with Lovable, Bolt, Replit.
Lovable projects contain no rewrite rule of any kind.
100 public Lovable repositories, read 2026-08-03 · method and scripts in the measurements
What is actually happening
A single-page app is one HTML file plus a bundle of JavaScript. Inside the app, clicking a link rewrites the address bar in the browser without asking the server for anything.
Reloading, or opening a link somebody sent, asks the server directly. The server looks for a file called `pricing`, finds nothing, and answers 404. Your app is intact — it was simply never loaded.
The preview provided by the builder answers every address with the same HTML file, which is why it works there. A plain static host does not do that unless it is told to.
Confirm it in one command
curl -sI https://yourapp.com/pricing | head -1
HTTP/2 200 means the server answers for that address. 404 means nothing does, and the app never gets a chance to load.
Fixing it yourself
- On Netlify: a file called `_redirects` in `public/` containing `/* /index.html 200`.
- On Vercel: a `vercel.json` with a rewrite of every path to `/index.html`.
- On your own nginx: `try_files $uri $uri/ /index.html;` inside the `location /` block.
- Test it the same way afterwards: request an inner route with curl and expect 200.
Where it stops being a small job
When the same rule breaks your static assets — a rewrite that catches everything will happily return HTML for a missing JavaScript file, and the browser then reports a syntax error in code that is fine. Getting both right at once is where this stops being a five-minute job.
If the rewrite rule turned out to break your scripts instead, that is the second half of the same problem and it is worth an hour of somebody else's time. Send the address and we will tell you which half you are on.
Send us the app