Heroku部署的React+Node.js Web应用无法访问/pages路径求助
It looks like you're hitting a super common issue with single-page applications (SPAs) deployed on Heroku: client-side routing breaks when accessing subpaths directly. Let's break down why this happens and how to fix it quickly:
Why This Happens
React uses client-side routing (via react-router), which means all the routing logic runs right in your browser. When you visit https://reactshoppingapp.herokuapp.com/signin directly, Heroku's web server tries to look for a physical file at that path (like signin.html), which doesn't exist—your app only has one entry point: index.html. Instead of serving up the React app (which would then handle the routing), the server throws a 404 error.
Solution 1: Use the serve Package (Perfect for Create React App Projects)
This is the simplest fix if your project was bootstrapped with Create React App:
- Install the
servepackage as a dev dependency:npm install serve --save-dev - Update your
package.jsonscripts to useservefor production, and add a post-build command to ensure Heroku generates your app's build folder:"scripts": { "start": "serve -s build", "build": "react-scripts build", "heroku-postbuild": "npm run build" } - Add an
enginesfield topackage.jsonto specify your Node.js version (match the version you use locally to avoid compatibility issues):"engines": { "node": ">=14.x" } - Commit these changes and redeploy to Heroku:
git add . git commit -m "Fix SPA routing on Heroku" git push heroku main
Solution 2: Use a Custom Express Server
If you prefer a more flexible setup, create an Express server that serves your build files and redirects all requests to index.html:
- Install Express:
npm install express --save - Create a
server.jsfile in your project root with this code:const express = require('express'); const path = require('path'); const app = express(); // Serve static files from the build folder app.use(express.static(path.join(__dirname, 'build'))); // Catch all routes and return the React app app.get('*', (req, res) => { res.sendFile(path.join(__dirname, 'build', 'index.html')); }); // Use Heroku's assigned port or 3000 for local testing const PORT = process.env.PORT || 3000; app.listen(PORT, () => { console.log(`Server running on port ${PORT}`); }); - Update your
package.jsonscripts:"scripts": { "start": "node server.js", "build": "react-scripts build", "heroku-postbuild": "npm run build" } - Add the
enginesfield as in Solution 1, then commit and redeploy.
Quick Additional Checks
- Double-check that your React app uses
BrowserRouter(notHashRouter) fromreact-router-dom—clean URLs without#fragments require this. - Verify Heroku's build logs if you run into issues: run
heroku logs --tailin your terminal to make sure thebuildfolder is generated correctly with no errors.
内容的提问来源于stack exchange,提问作者Tammy

