Your React application works perfectly on localhost.
You run the production build, upload it to your server, open the website and…
Nothing. Just a blank white page.
This is one of those React problems that can look much worse than it actually is.
A blank page usually doesn’t mean React completely failed to deploy. More often, the browser downloaded something, but a JavaScript error, incorrect asset path, routing problem, missing environment variable or API failure prevented the application from rendering correctly.
Instead of rebuilding the entire project or randomly changing hosting settings, let’s troubleshoot the problem systematically.
Why Does a React App Show a Blank Page After Deployment?
A React application can show a blank page after deployment because of several different issues:
- JavaScript runtime errors
- Incorrect asset or base paths
- Missing production build files
- Wrong environment variables
- React Router configuration
- Server rewrite configuration
- API or CORS errors
- Incorrect deployment directory
- Case-sensitive imports
- Cached old application files
The important thing is to determine whether the problem is happening during:
Build → Asset loading → JavaScript execution → Routing → API communication → Rendering
Once you know which stage is failing, the problem becomes much easier to solve.
1. Check the Browser Console First
Before changing your React code, open the deployed application in Chrome or another browser.
Open:
Developer Tools → Console
On Chrome you can usually press F12, Ctrl + Shift + I, or right-click the page and choose Inspect.
Look for red errors.
For example:
Uncaught TypeError: Cannot read properties of undefined
or:
Failed to load resource: the server responded with a status of 404
or:
Uncaught SyntaxError: Unexpected token '<'
or:
Access to fetch at ... has been blocked by CORS policy
These messages are far more useful than the blank screen itself.
A white page is only the symptom.
The browser console often tells you the actual problem.
2. Check the Network Tab
If the console doesn’t immediately explain the issue, open:
Developer Tools → Network
Refresh the page.
Look for failed requests, particularly:
- JavaScript files
- CSS files
- API requests
- Images
- JSON/config files
Pay attention to HTTP responses such as:
404
403
500
If your JavaScript bundle returns 404, React may never start.
For example, your HTML might request:
/assets/index-AbCd123.js
while the actual application is deployed under:
/my-app/assets/index-AbCd123.js
That’s not really a React component problem.
It’s a deployment/base-path problem.
3. Make Sure You Deployed the Production Build
A surprisingly common deployment mistake is uploading the wrong directory.
Normally you first run:
npm run build
What gets generated depends on your React tooling.
For a Vite application, the default output directory is commonly:
dist/
Create React App traditionally generates:
build/
You generally deploy the generated production files, not simply upload your entire src directory and expect the browser to run it.
For Vite, a typical deployment contains files similar to:
dist/
├── index.html
└── assets/
├── index-xxxxx.js
└── index-xxxxx.css
Verify that the files generated by your latest build are actually the files deployed to production.
4. Test the Production Build Locally
Before blaming the hosting server, test the production build.
For Vite, you can commonly use:
npm run build
npm run preview
If the production build already shows a blank page locally, the hosting server probably isn’t your first problem.
If it works with the production preview but fails after deployment, investigate differences between:
local production preview vs live hosting
That narrows the search considerably.
5. Check the Base Path in Vite
This is one of the first things to inspect when a Vite React app works locally but fails after being deployed into a subdirectory.
Suppose your application is hosted at:
https://example.com/customer-app/
instead of:
https://example.com/
Your assets need to resolve correctly from that deployment location.
Vite supports a base configuration in vite.config.js.
For example:
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
export default defineConfig({
plugins: [react()],
base: '/customer-app/',
});
Then rebuild:
npm run build
and deploy the newly generated output.
Don’t simply change vite.config.js on the server and expect existing build files to update.
The application must be rebuilt.
6. Check Create React App’s Deployment Path
If you’re maintaining an older Create React App project, deployment-path configuration may also affect generated asset URLs.
For example, CRA projects sometimes use the homepage field in package.json to control deployment paths.
A project deployed at a subdirectory needs configuration appropriate for that actual location.
The exact solution depends on your application and deployment strategy, so don’t copy a random homepage value without understanding where the app is being served.
7. Inspect the Generated index.html
Open your production index.html.
Look at the generated JavaScript and CSS URLs.
For example:
<script type="module" src="/assets/index-abc123.js"></script>
Now request that URL directly from the production website.
Does it return the JavaScript file?
Or does it return:
- 404 page
- Hosting error
- Your React
index.html - Login page
- Server-generated HTML
This test is particularly useful for errors such as:
Unexpected token '<'
Sometimes the browser expects JavaScript but the server returns an HTML document instead.
The browser then tries to parse HTML as JavaScript and fails.
8. Check React Router
Another common deployment problem appears when using client-side routing.
Suppose your application has:
/
/login
/dashboard
/profile
Navigating inside the application works.
But refreshing:
https://example.com/dashboard
produces a server 404 or blank/error page.
Why?
React Router understands /dashboard.
Your Apache or Nginx server may not.
The server receives a request for /dashboard and tries to find a physical file or directory with that name.
For a typical single-page application using browser history routing, the server usually needs to fall back to:
index.html
for routes that should be handled by React.
9. React Router on Apache
If your React SPA is hosted on Apache, rewrite configuration may be required.
A common concept is:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]
</IfModule>
But don’t blindly paste this into every server.
If your React application is hosted inside a subdirectory, the rewrite base and target may need to reflect that deployment.
Also be careful when React is hosted alongside WordPress, Laravel or another application. An overly broad rewrite rule can interfere with the other application.
10. React Router on Nginx
The same concept applies to Nginx.
For a typical SPA, configuration often needs to attempt the requested resource and then fall back to index.html.
Conceptually:
location / {
try_files $uri $uri/ /index.html;
}
Your actual configuration depends on where the application is hosted and what else the server is serving.
After modifying Nginx configuration, validate it before reloading the service.
11. Check Your Environment Variables
This is another major reason a React application works locally but fails in production.
Locally you might have:
.env
containing your API URL.
But the production build may not receive the same environment variable.
For Vite, client-exposed environment variables conventionally use the VITE_ prefix.
For example:
VITE_API_URL=https://api.example.com
Then:
const apiUrl = import.meta.env.VITE_API_URL;
If VITE_API_URL is missing during the production build, your application may attempt requests using an undefined or incorrect URL.
Remember:
Frontend environment variables are usually incorporated during the build process.
Changing .env after the application has already been built won’t necessarily change the generated JavaScript bundle.
After changing build-time environment configuration:
npm run build
again.
12. Don’t Put Secrets in React Environment Variables
An important security point:
Variables exposed to browser-side React code are not private simply because they’re stored in .env.
If the application needs a value in the browser, assume users can inspect it.
Don’t put sensitive server-side secrets such as:
- Private API secrets
- Database passwords
- Server credentials
- Private signing keys
inside client-side React environment variables.
Secrets belong on your backend.
13. Check Whether the API URL Still Points to Localhost
This happens more often than you’d expect.
Your application works locally because it calls:
http://localhost:8000/api
You deploy React.
But the production build still calls:
http://localhost:8000/api
On a visitor’s computer, localhost means their computer, not your production API server.
Your production environment should point to the appropriate live API endpoint.
Use the Network tab to see exactly which URL the deployed application is requesting.
Don’t assume your environment configuration was loaded correctly.
14. Check for CORS Errors
Suppose your frontend is hosted at:
https://app.example.com
and your API is hosted at:
https://api.example.com
The browser enforces cross-origin rules.
If the backend isn’t configured to permit the required origin/methods/headers, you may see a CORS error.
For example:
blocked by CORS policy
This isn’t normally solved by randomly adding headers to your React application.
CORS policy is primarily enforced based on the server’s response.
Investigate the API/backend configuration.
We’ll cover CORS troubleshooting separately in our upcoming Express/Node.js article.
15. Make Sure Your UI Handles API Failures
An API failure shouldn’t ideally turn your entire application into a blank page.
Consider code that assumes data always exists:
return users.map((user) => (
<div key={user.id}>
{user.name}
</div>
));
If users unexpectedly becomes undefined, rendering may fail.
Your application should account for:
- Loading state
- Empty state
- Error state
- Unexpected API responses
For example:
if (loading) {
return <p>Loading...</p>;
}
if (error) {
return <p>Unable to load data.</p>;
}
if (!Array.isArray(users)) {
return <p>No users available.</p>;
}
Production APIs fail sometimes.
Your UI should fail gracefully rather than displaying an unexplained white screen.
16. Check Case-Sensitive Imports
This is a classic deployment issue.
On a local environment, you might have:
components/Header.jsx
but import:
import Header from './components/header';
Some development environments may tolerate filename case differences.
A Linux production server may not.
Header.jsx
and:
header.jsx
are not necessarily the same filename.
Review import paths when the build or production environment reports missing modules/files.
17. Check for JavaScript Errors That Only Happen in Production
Production builds can expose assumptions that weren’t obvious during development.
Check for:
- Undefined variables
- Null values
- Incorrect API response assumptions
- Environment-dependent code
- Browser API differences
- Third-party script failures
- Minification/build issues
- Incorrect dynamic imports
Again, start with the browser console.
Don’t debug a blank React page while ignoring a clear exception sitting in DevTools.
18. Check Lazy Loading and Dynamic Imports
Suppose you’re using:
const Dashboard = React.lazy(
() => import('./pages/Dashboard')
);
The initial page might load correctly, but navigating to Dashboard fails because its generated chunk can’t be downloaded.
Check Network for failed JavaScript chunk requests.
This can happen after deployments when:
- Old HTML is cached
- New build removed old hashed chunks
- CDN still serves stale files
- Service worker has an older application version
- Asset paths changed
A hard refresh may appear to solve the problem for you, but don’t assume every user’s cache will behave the same way.
Your deployment/cache strategy should handle versioned assets correctly.
19. Clear Browser, CDN and Hosting Cache
Caching can create a confusing combination:
Old index.html + new JavaScript files
or:
New index.html + old cached assets
If you use:
- Browser caching
- Cloudflare/CDN
- Hosting cache
- Reverse proxy
- Service worker/PWA caching
make sure you’re testing the current deployment.
Use an incognito/private window as a quick comparison, but treat it as a diagnostic step rather than the permanent solution.
20. Check the Browser Console for Mixed Content
Suppose your React website uses:
https://example.com
but the API request goes to:
http://api.example.com
The browser may block insecure content loaded from a secure HTTPS page.
Check DevTools for mixed-content warnings.
In production, use properly configured HTTPS endpoints.
21. Check Authentication and Redirect Logic
Sometimes the application isn’t technically blank.
It’s stuck in broken navigation logic.
For example:
App starts
↓
Check token
↓
Redirect to login
↓
Login detects token
↓
Redirect to dashboard
↓
Dashboard rejects session
↓
Redirect to login
This can create loops, flashes or seemingly blank screens.
Check:
- Authentication state
- Token storage
- Token expiry
- API session validation
- Protected route logic
- Redirect conditions
Add controlled logging during development to understand which route/state is repeatedly changing.
22. Check Your Root Element
React needs the correct DOM element to mount the application.
Your HTML may contain:
<div id="root"></div>
while your application expects:
document.getElementById('root')
If the IDs don’t match, React can’t mount where expected.
This isn’t the most common deployment-only issue, but it’s worth checking if index.html was customized during deployment.
23. Check Deployment Directory Structure
Let’s say you want the application available at:
https://example.com/app/
but upload your files as:
public_html/
app/
dist/
index.html
assets/
Your actual URL may then effectively require:
/app/dist/
instead of /app/.
Normally you want the contents of the generated output directory placed in the intended web root for that application, not necessarily the output directory itself.
Always verify where index.html actually lives relative to the public URL.
24. React App Works on / but Refreshing /dashboard Fails
This deserves its own example because it’s extremely common.
Suppose:
https://example.com/
works.
You click Dashboard.
React Router navigates to:
https://example.com/dashboard
Everything works.
Now press Refresh.
You get 404.
That strongly suggests:
React Router is working, but your web server doesn’t have SPA fallback routing configured correctly.
Investigate Apache/Nginx/hosting rewrite rules rather than rewriting your React Dashboard component.
25. React App Works Locally but Is Blank on Production
Here’s a practical troubleshooting sequence.
Step 1
Open DevTools Console.
You see:
Failed to load resource: 404
for:
/assets/index-abc123.js
Step 2
Open Network.
The JavaScript asset really is returning 404.
Step 3
Check deployment URL.
Your application is hosted at:
https://example.com/client/
but generated assets point to:
https://example.com/assets/
Step 4
Correct the Vite base configuration:
export default defineConfig({
plugins: [react()],
base: '/client/',
});
Step 5
Rebuild:
npm run build
Step 6
Deploy the new dist output.
The application loads.
The problem wasn’t:
“React doesn’t work on the server.”
It was:
Incorrect production asset paths.
26. Example: React Page Blank Because of API Failure
Another scenario:
Your app loads, but the main component depends on an API request.
DevTools shows:
GET http://localhost:8000/api/products
Production visitors obviously can’t access your development API.
You inspect the environment configuration and discover the production API variable wasn’t available during the build.
Correct the environment configuration, rebuild and redeploy.
Again, the blank page is only the visible symptom.
React Blank Page Troubleshooting Checklist
If your React application shows a blank page after deployment, check these in order:
- Open the browser console
- Check Network for failed assets
- Confirm the production build completed successfully
- Test the production build locally
- Verify the correct build directory was uploaded
- Check generated JavaScript/CSS paths
- Verify Vite
baseconfiguration - Check CRA deployment configuration if applicable
- Verify React Router fallback configuration
- Check production environment variables
- Verify the production API URL
- Check CORS errors
- Check HTTPS/mixed-content problems
- Review case-sensitive imports
- Check lazy-loaded chunks
- Clear browser/CDN/hosting caches
- Check authentication redirects
- Verify the React root element
- Check the deployment directory
- Rebuild and redeploy after configuration changes
The key is to diagnose the failure in layers instead of changing everything at once.
How to Prevent React Deployment Problems
Test the Production Build Before Deployment
Don’t rely only on:
npm run dev
Test what you’re actually going to deploy.
Maintain Separate Environment Configuration
Keep development and production API URLs clearly separated.
Use a Repeatable Deployment Process
Avoid manually uploading random files from different builds.
Check the Browser Console After Every Deployment
A deployment isn’t finished just because the upload completed.
Add Error Handling
Your entire application shouldn’t become unusable because one API request failed.
Use Error Boundaries Where Appropriate
React error boundaries can help prevent certain rendering errors from taking down larger portions of the UI and can provide a better fallback experience.
Monitor Production Errors
For important applications, production error monitoring can help you discover frontend exceptions before users start reporting blank screens.
Final Thoughts
A React blank page after deployment can feel like a hosting disaster, especially when the application works perfectly locally.
But the problem usually becomes much clearer once you stop looking at the white page and start looking at:
Console → Network → Build → Paths → Environment → Router → API → Server
Start with the browser’s error messages.
Determine whether JavaScript assets are loading.
Verify the production configuration.
Then investigate routing and API communication.
A systematic troubleshooting process is faster and safer than repeatedly rebuilding the project and hoping the problem disappears.
Need Web Application Help?
Still Seeing a Blank Page After Deploying React?
Production React issues can involve multiple layers: frontend code, Vite/build configuration, React Router, APIs, CORS, authentication, Apache/Nginx and hosting configuration.
- React deployment troubleshooting
- React and Next.js development
- Node.js and Express APIs
- REST API integrations
- Authentication issues
- Performance optimization
- Existing application debugging
- Custom web application development
Frequently Asked Questions
Common causes include JavaScript errors, incorrect asset paths, missing environment variables, React Router/server configuration problems, API failures, CORS errors and incorrect deployment directories.
Start with the browser Console and Network tabs.
Development and production environments can differ in asset paths, environment variables, API URLs, routing behaviour and build optimization.
Test the production build locally and inspect the browser console for the exact failure.
One common cause is incorrect asset paths when the application is deployed under a subdirectory. Check Vite's base configuration, rebuild the application and verify generated asset URLs.
Also check browser console errors before assuming base is the problem.
Client-side navigation is handled by React Router, while a browser refresh sends the route directly to your web server.
For an SPA using browser-history routing, your server generally needs appropriate fallback configuration so application routes are served through index.html.
Yes, indirectly. If your application depends on API data and doesn't handle API failures correctly, a blocked cross-origin request can lead to rendering errors or an unusable screen.
Check the browser console and Network tab.
Your production environment variable may be missing, incorrectly configured or not present when the application was built.
Check the actual request URL in DevTools and rebuild after correcting build-time environment configuration.
For environment values incorporated into the frontend bundle at build time, yes. Update the configuration and generate a new production build before deploying it.
A common reason is that the browser requested a JavaScript file but the server returned HTML instead, such as a 404 page or index.html.
Inspect the failing request in the Network tab and verify its URL and response.