部署至Vercel后主页正常但页面链接跳转404问题求助
问题:Express+React+GraphQL应用部署到Vercel后路由跳转404
我有一个采用Express作为后端、React作为前端并使用GraphQL的应用,该应用在Heroku上可正常运行,但由于Heroku取消免费套餐,我尝试将其部署至Vercel。部署后主页可正常访问,但点击任何链接都会出现404错误。
项目结构
- 前端代码位于
client文件夹 - 后端代码位于
server文件夹
相关代码
server/server.js
const express = require('express'); const { ApolloServer } = require('apollo-server-express'); const path = require('path'); const { typeDefs, resolvers } = require('./schemas'); const db = require('./config/connection'); const PORT = process.env.PORT || 3001; const app = express(); const server = new ApolloServer({ typeDefs, resolvers, }); app.use(express.urlencoded({ extended: true })); app.use(express.json()); if (process.env.NODE_ENV === 'production') { app.use(express.static(path.join(__dirname, '../client/build'))); } app.get('*', function (_, res) { res.sendFile( path.join(__dirname, '../client/build/index.html'), function (err) { if (err) { res.status(500).send(err); } } ); }); // Create a new instance of an Apollo server with the Graphql schema const startApolloServer = async (typeDefs, resolvers) => { await server.start(); server.applyMiddleware({ app }); db.once('open', () => { app.listen(PORT, () => { console.log(`API server running on port ${PORT}!`); console.log( `Use GraphQL at http://localhost:${PORT}${server.graphqlPath}` ); }); }); }; // Call the asyn funcion to start the server startApolloServer(typeDefs, resolvers);
client/src/app.js
import { ApolloClient, InMemoryCache, ApolloProvider } from '@apollo/client'; import { Route, Routes, BrowserRouter as Router } from 'react-router-dom'; import Home from './pages/Home'; import About from './pages/About'; import Header from './components/Header'; import Test from './pages/Test'; // Construct our main GraphQL API endpoint const client = new ApolloClient({ uri: '/graphql', cache: new InMemoryCache(), }); function App() { return ( <ApolloProvider client={client}> <Router> <Header /> <main> <Routes> <Route path='/' element={<Home />}> Home </Route> <Route path='/about' element={<About />}> About </Route> <Route path='/test' element={<Test />}> Test </Route> </Routes> </main> </Router> </ApolloProvider> ); } export default App;
解决方案
问题根源是Vercel的路由规则默认优先处理静态文件,不会将非根路径的请求转发到Express后端的* fallback路由,导致React的客户端路由无法生效。
1. 添加Vercel路由重写配置
在项目根目录创建vercel.json文件,配置所有请求转发到Express入口文件:
{ "rewrites": [ { "source": "/(.*)", "destination": "/server/server.js" } ] }
2. 确认Express的Fallback路由逻辑
你的Express代码中已经包含了app.get('*', ...)的逻辑,会将所有非API请求返回client/build/index.html,这部分无需修改,确保生产环境下能正确找到静态文件路径即可。
3. 配置Vercel部署参数
在Vercel项目的部署设置中:
- Root Directory保持默认(项目根目录)
- Build Command设置为
npm install && cd client && npm install && npm run build(根据你的实际依赖安装和构建命令调整) - Output Directory无需设置,由Express负责静态文件服务
4. 验证部署
重新部署后,点击React路由链接时,Vercel会将请求转发到Express,Express返回index.html,由React的BrowserRouter处理客户端路由,即可解决404问题。
内容的提问来源于stack exchange,提问作者Stephen Scott Moore
相关产品推荐
相关产品推荐

