Your React app is blank after deploying
npm run dev: perfect. Deployed: a white page. Nothing works, and — if this is
your first React deployment — nothing tells you why.
The reason this exact failure is so common is that development and production are different programs. The dev server serves unbuilt modules from memory, injects variables, rewrites every URL, and forgives. The build is static files on a host that does none of that. Every difference between the two is a place where "works locally" quietly ends.
Check the five causes in this order — it is the order of how often they happen.
0. First, look at the right thing
Open the deployed site, press F12, and look at two tabs:
- Console — the first red line is the error that matters.
- Network, then reload — a red row on a
.jsfile means the page could not even load its code.
That second check decides everything below: console errors mean your code ran and crashed; a red script in Network means it never ran at all.
1. The page loads its JavaScript from the wrong place
Symptom: blank page, empty console, and the bundle (/assets/index-….js)
red in the Network tab with a 404 — often because the site lives under a
subpath (GitHub Pages is the classic: username.github.io/my-app/ while the
HTML asks for /assets/… at the domain root).
Fix: tell the build where it lives.
// vite.config.ts — deploying under https://user.github.io/my-app/
export default defineConfig({
base: '/my-app/',
});
If the app deploys at a domain root, base must stay / — an AI that
"fixed" GitHub Pages earlier may have left a subpath behind that now breaks
the root deployment. This cuts both ways.
2. The router and the host disagree
Symptom: the home page works; opening /dashboard directly or refreshing
there gives a blank page or the host's 404. React Router (a BrowserRouter)
handles routes in the browser, but on a refresh the host is asked for
/dashboard as a file, and no such file exists.
Fix: one rewrite rule on the host, telling it to serve index.html for
every route. Two lines, different per host — the SPA refresh guide has each
one. If the app also lives under a subpath, the
router needs to know: <BrowserRouter basename="/my-app">.
3. An environment variable was not there at build time
Symptom: console errors on load like supabaseUrl is required. or
Cannot read properties of undefined pointing into initialization code.
Frontend env variables (VITE_*, REACT_APP_*, NEXT_PUBLIC_*) are pasted
into the code when the build runs. Your local .env file does not travel
to the host; the host must have the variables set and run a fresh build
after. Full mechanics and per-host steps: env variables
undefined.
4. The code crashes — in minified form
Symptom: the console shows something like:
Uncaught Error: Minified React error #310; visit https://react.dev/errors/310
for the full message
Production React strips error text to keep the bundle small and gives you a numbered code plus a decoder link. Open the link — that decoded sentence is the real error. The frequent ones in generated apps: #418 / #423 (hydration mismatch — guide), #310 (hooks called conditionally), #185 (a state update loop).
If the crash is an ordinary TypeError on data, that family has its own
guide.
5. It crashes, and nothing catches it
Any unhandled render error unmounts the entire React tree — that is why the failure mode is a blank page rather than a broken section. Whatever today's root cause is, add an error boundary so the next failure identifies itself:
Paste this to the AI that built your app
My React app deploys blank. Diagnosis so far: - Console first red line: [paste it, or "console is empty"] - Network tab: [is the main .js bundle loading, or red/404?] - Host: [Netlify / Vercel / GitHub Pages / other], deployed at [domain root / subpath]. Work through, in order: the build base path versus where the site is hosted; router basename and the host's SPA rewrite; environment variables read by the code but missing on the host; the decoded meaning of any minified React error. Fix the root cause, and add a top-level React error boundary that shows a readable message instead of a blank page.
Prove it
Open the deployed URL in a private window, console open: page renders, no red lines, and the main flows survive a hard refresh on a deep link. All three, not the first one.
Questions people also ask
Why does it work with npm run dev and not in production?
The dev server serves unbuilt code from memory with its own tolerant defaults; production serves a built bundle from a real host with your configuration. Base paths, environment variables and routing rewrites only take effect — and only fail — in the built version.
The console shows no errors at all and the page is still blank. What then?
Look at the Network tab instead: if the page's own JavaScript file is red (404), no code ever ran, so nothing could log. That is a base path problem — the HTML is asking for its scripts at the wrong address.
What is a 'Minified React error #310' or similar?
Production React replaces full messages with numbered codes. The error text includes a link to the decoder — open it, and treat the decoded message as the real error. #418/#423 are hydration mismatches, #310 is a hooks-order bug, #185 is an update loop.