解决 Vite 项目部署后仅显示首页、无法访问子路由(如 /login)的问题

解决 Vite 项目部署后仅显示首页、无法访问子路由(如 /login)的问题

Vite 构建的单页应用(SPA)部署到静态托管平台(如 Vercel、Netlify、Nginx)后,直接访问 /login 等子路径返回 404 或跳回首页,根本原因是服务端未正确配置 SPA 路由回退机制。

vite 构建的单页应用(spa)部署到静态托管平台(如 vercel、netlify、nginx)后,直接访问 `/login` 等子路径返回 404 或跳回首页,根本原因是服务端未正确配置 spa 路由回退机制。

当你在本地开发时(npm run dev),Vite 开发服务器默认启用 HTML 5 History 模式路由的自动回退——即所有未知路径均返回 index.html,再由前端路由(如 Vue Router 或 React Router)接管并渲染对应页面。但生产环境的静态服务器默认不具备该能力:它会严格按文件路径查找资源。例如请求 https://your-site.com/login,服务器会尝试寻找 ./login/index.html 或 ./login.html,而你的构建产物中通常只有 index.html 和静态资源,因此返回 404 或默认首页。

✅ 正确解决方案(二选一)

方案一:配置服务端路由回退(推荐,保留 History 模式)

确保所有非资源请求(即非 .js/.css/.png 等)均返回 index.html,让前端路由接管。

  • Vercel(你当前使用的平台):在项目根目录添加 vercel.json:

    {   "rewrites": [     { "source": "/(.*)", "destination": "/index.html" }   ] }

    ✅ 部署后,所有路径(如 /login, /dashboard)都会加载 index.html,Vue Router/React Router 即可正常解析。

  • Netlify:在根目录创建 _redirects 文件:

    /* /index.html 200
  • Nginx(自托管):在 location 块中添加:

    location / {   try_files $uri $uri/ /index.html; }

方案二:改用 Hash 模式路由(快速验证,不推荐长期使用)

修改前端路由配置,避免依赖服务端支持:

  • Vue Router(v4)

    // router/index.ts import { createRouter, createWebHashHistory } from 'vue-router'  const router = createRouter({   history: createWebHashHistory(), // ← 替换为 hash 模式   routes: [/* ... */] })
  • React Router(v6+)

    import { HashRouter } from 'react-router-dom'  ReactDOM.createRoot(document.getElementById('root')!).render(   <HashRouter> {/* ← 替换 BrowserRouter */}     <App />   </HashRouter> )

    此时 URL 变为 https://yoursite.com/#/login,无需服务端配置,但 SEO 和分享体验较差。

⚠️ 注意事项

  • 检查 vite.config.ts 中 base 配置是否与部署路径匹配(如部署在子路径 /app/,需设 base: ‘/app/’);
  • 确保构建产物中 index.html 的 <script> 引入路径正确(Vite 默认已处理,无需手动修改);</script>
  • 不要将路由组件路径误写为服务端真实目录(如 src/pages/Login.vue ≠ 服务器 /login/ 目录);
  • 若使用 vite-plugin-pages 或 @vitejs/plugin-react-swc 等插件,请确认其与路由模式兼容。

部署不是终点,而是前端路由与服务端协作的起点。选择方案一(服务端重写)是现代 SPA 的标准实践,既保持语义化 URL,又确保全路径可直达、可刷新、可收藏。