QAlaunch

Lovable app gives 404 on refresh after export: the fix per host

An exported Lovable React + Vite app returns 404 on refresh because it is a single-page app: the host looks for a file called /about, finds none, and never loads index.html where the router lives. Add a fallback so every unknown path serves index.html, using public/_redirects on Netlify or a rewrite in vercel.json on Vercel. On Lovable's own hosting this is handled for you, so the problem only appears after you move the code.

Opens your site in a real browser on desktop and phone. Free, about two minutes, no signup. Full report from $19.

What you'll see

The homepage loads on your new host and clicking through the menu works. But pressing refresh on /about, opening /dashboard from a bookmark, or following a link someone shared gives the host's own error, such as Netlify's "Page not found – Looks like you've followed a broken link" or Vercel's 404 page.

Why it happens

1. Client-side routing needs a fallback

Older Lovable projects use React Router inside one index.html. Inside the app, links change the URL without asking the server for anything. A refresh asks the server for /about directly, and a plain static host has no such file.

2. No rewrite rule was exported

Lovable's hosting serves index.html for every route, so the project never needed a rule. When you sync to GitHub and deploy elsewhere, nothing tells the new host to do the same.

3. A netlify.toml rule that is never read

Netlify only reads netlify.toml redirects during its own build. If you drag and drop a dist folder, or a tool uploads prebuilt files, that step is skipped and the rule is ignored, which is why a _redirects file inside the output is more reliable.

How to fix it

  1. Confirm the project type first. If package.json uses Vite and react-router-dom, this guide applies. Projects created on TanStack Start from May 2026 render on a server and need a host that runs Node, not just a static fallback.
  2. For Netlify, create a file at public/_redirects containing one line: /* /index.html 200. Vite copies everything in public/ into dist/ on build, so the rule ships with every deploy.
  3. For Vercel, add vercel.json at the project root with { "rewrites": [ { "source": "/(.*)", "destination": "/index.html" } ] }. Vercel serves real files first, so images and scripts are unaffected.
  4. For GitHub Pages, which has no rewrites, copy index.html to 404.html in the build output, or switch to HashRouter. Also set base in vite.config to /your-repo-name/ if the site lives in a subfolder.
  5. Add a catch-all route inside the app that shows a proper "page not found" screen, so genuinely wrong URLs still tell the visitor something useful once the host stops returning 404.
  6. Redeploy, then open three deep links in a fresh private window and press refresh on each.

Prompt to paste into Lovable

This app will be hosted on [Netlify/Vercel]. Add the single-page-app fallback so direct visits and refreshes on any route serve index.html: for Netlify add public/_redirects with "/*  /index.html  200"; for Vercel add vercel.json with a rewrite from "/(.*)" to "/index.html". Also add an in-app 404 page for unknown routes. Do not change routing otherwise.

How to check it's fixed

  • Paste several deep URLs straight into a new private window and refresh each one; every page should render, not the host's error page.
  • In DevTools > Network, the document request for a deep URL should return 200, and a made-up URL should show your in-app 404 screen.

What a QAlaunch scan shows for this

  • Internal links on the homepage that return 404 when the scan loads them directly, which is exactly how a refresh behaves.
  • How the site answers a path that does not exist: the host's bare error page, or your own 404 screen.
  • A free scan covers the homepage and its links; a paid report loads up to 10 pages directly, which catches deep routes too.

See exactly what a full report contains in the sample report.

Frequently asked questions

Why does it work when I click links but not when I refresh?

Clicking a link inside the app never asks the server for a page; the router swaps the content in the browser. Refreshing makes a real request for that path, and without a fallback rule the host has nothing to send back.

Will the fallback rule break my images or API calls?

No. Netlify and Vercel serve files that exist before applying the rule, so assets in dist load normally. Only paths with no matching file get index.html.

Does this happen on lovable.app or my Lovable custom domain?

No. Lovable's own hosting already serves the app for every route. If you see 404s there, the link itself points at a route the app does not define.

Done for you · not automated

Rather have a QA engineer test it by hand?

If this is a site you're launching or handing to a client, I'll go through it by hand, including the Lovable-specific issues a scan can't reach, like logged-in flows.

$299one-time · 3 business days
  • Up to 10 key pages tested by hand, not a scan
  • Every flow a customer uses: forms, sign-up, checkout, booking
  • Real mobile and desktop browsers
  • A written report in plain language, with screenshots
  • A 15-minute call to walk you through it
  • 10 years of professional QA experience

Tell me about your site and I'll reply personally, usually the same day.

No payment now. I'll confirm scope and price first.

More for Lovable: all Lovable fixes · Lovable testing · 9 bugs every AI-built site ships with

Written by Waqas Ahmad, QA engineer with 10 years of professional testing experience. Last checked October 26, 2026.

Sources: Netlify forum: 404 on page refresh with netlify.toml · Vercel community: React Vite production 404 on nested routes · RapidDev: fixing 404 errors on refresh in Lovable SPAs