SVG 通过 <img> 标签引用时在本地正常,但部署到 Vercel 或 Netlify 后失效,根本原因在于构建路径未适配生产环境的静态资源目录结构。
svg 通过 `` 标签引用时在本地正常,但部署到 vercel 或 netlify 后失效,根本原因在于构建路径未适配生产环境的静态资源目录结构。
在现代前端项目(如 Vite、Create React App、Vue CLI 等)中,开发者常习惯使用相对路径(如 /src/assets/logo.svg)直接引用 SVG 文件。然而,该路径仅在开发服务器(如 vite dev)下有效——因为开发服务器会将整个源码目录映射为根路径;而构建部署后,打包工具(如 Vite 的 build)会将静态资源输出至 dist/assets/(或类似)目录,并自动重命名哈希化文件(如 logo-bookmark-white.a1b2c3d4.svg),同时仅将 public/ 目录下的内容原样复制到 dist/ 根目录。
因此,以下写法在部署后必然失败:
<!-- ❌ 错误:/src/assets/ 是源码路径,构建后不存在 --> <img src="/src/assets/logo-bookmark-white.svg" alt="Logo" />
✅ 正确做法取决于你的项目结构和构建工具:
✅ 方案一:将 SVG 移入 public/ 目录(推荐,简单可靠)
将 SVG 文件放入 public/assets/logo-bookmark-white.svg,然后使用以 / 开头的绝对路径(对应部署后的域名根路径):
<!-- ✅ 正确:/assets/ 对应 public/assets/ --> <img src="/assets/logo-bookmark-white.svg" alt="Logo" />
? 提示:public/ 下的文件不会被构建处理,路径保持原样,适合 logo、favicon 等静态资源。
✅ 方案二:使用模块导入(更现代,支持类型安全与 Tree-shaking)
在支持 ES 模块的构建工具(Vite、Webpack 5+)中,可直接导入 SVG 作为 URL:
// TypeScript / JavaScript
import logoSvg from '@/assets/logo-bookmark-white.svg'; // 别名需已配置
// 在 JSX/TSX 中
<img src={logoSvg} alt="Logo" />或在 Vue SFC 中:
<template> <img :src="logoSvg" alt="Logo" /> </template> <script setup> import logoSvg from '@/assets/logo-bookmark-white.svg'; </script>
此时构建工具会自动将其纳入资源处理流程,返回正确的哈希化路径(如 /assets/logo-bookmark-white.8f2e1a7d.svg),确保部署一致性。
⚠️ 注意事项
- 不要使用 ./src/assets/... 路径(如答案中建议的 <img src="./src/assets/..." />)——这属于无效路径,本地可能偶然工作(因开发服务器宽松),但部署后 404 是必然结果;
- 检查浏览器开发者工具的 Network 面板,确认 SVG 请求返回 404,并比对实际请求 URL 与 dist/ 目录结构;
- 若使用 Vite,确保 vite.config.ts 中 build.assetsDir 未意外修改默认行为;
- SVG 作为 <img> 引入时无法通过 CSS 控制内部样式(如 fill);如需动态着色,建议改用 <svg> 内联或 react-icons 等方案。
总结:路径失效的本质是开发与生产环境资源定位机制不同。坚持“public/ 存静态、src/assets/ 用模块导入”,即可彻底规避此类部署问题。










