You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在React Vite中使用SVGR导入public目录下的SVG文件?

解决React+Vite+SVGR导入public目录SVG并修改属性的问题

问题场景

我用React + Vite + SVGR开发项目,SVG文件放在public目录下,结构如下:

|
|- src
|- public
    |- icons
        |- svgs
            |- mySvg.svg
|- vite.config.ts
|- package.json

导入SVG时触发Vite报错:

public目录中的资源无法从JavaScript导入。
如果您打算导入该资源,请将文件放在src目录中,并使用/src/assets/icons/svgs/mySvg.svg代替/public/assets/icons/svgs/mySvg.svg。

同时有两个限制:

  • 不能用<img>标签引入SVG(需要修改SVG的属性,比如颜色、尺寸)
  • 不能把SVG移到src目录(希望保留public作为标准资源目录,兼容其他库的内置支持)

解决方案一:配置Vite+SVGR直接导入public目录SVG

1. 确认依赖安装

确保已安装SVGR相关插件:

npm install @svgr/core vite-plugin-svgr --save-dev

2. 修改Vite配置文件

在vite.config.ts中调整SVGR插件的匹配规则,让它覆盖public目录的SVG:

import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import svgr from 'vite-plugin-svgr';
import path from 'path';

export default defineConfig({
  plugins: [
    react(),
    svgr({
      // 匹配public目录下的所有SVG文件,路径根据项目根目录调整
      include: path.resolve(__dirname, 'public/icons/svgs/**/*.svg'),
      // SVGR的额外配置,比如启用title属性支持
      svgrOptions: {
        titleProp: true,
      },
    }),
  ],
  // 配置路径别名,简化导入路径
  resolve: {
    alias: {
      '@public': path.resolve(__dirname, 'public'),
    },
  },
});

3. 导入并使用SVG组件

现在可以直接把SVG作为React组件导入,还能通过props修改属性:

import MySvg from '@public/icons/svgs/mySvg.svg?react';

function App() {
  return (
    <div>
      {/* 直接修改SVG的fill、width等属性 */}
      <MySvg fill="#ff4444" width="50" height="50" />
    </div>
  );
}

export default App;

解决方案二:动态加载并解析SVG(无需修改Vite配置)

如果不想调整Vite配置,可以通过fetch动态加载SVG并解析为可修改属性的React元素:

import { useEffect, useState } from 'react';

function CustomSvg({ src, ...props }) {
  const [svgNode, setSvgNode] = useState(null);

  useEffect(() => {
    const loadAndParseSvg = async () => {
      const res = await fetch(src);
      const svgContent = await res.text();
      const parser = new DOMParser();
      const svgDoc = parser.parseFromString(svgContent, 'image/svg+xml');
      const svgElement = svgDoc.querySelector('svg');

      if (svgElement) {
        // 将传入的props转为SVG属性
        Object.entries(props).forEach(([key, val]) => {
          svgElement.setAttribute(key, String(val));
        });
        // 转为React元素渲染
        setSvgNode(
          <svg
            {...props}
            dangerouslySetInnerHTML={{ __html: svgElement.innerHTML }}
          />
        );
      }
    };

    loadAndParseSvg();
  }, [src, props]);

  return svgNode || <div>Loading...</div>;
}

// 使用示例
function App() {
  return (
    <div>
      <CustomSvg src="/icons/svgs/mySvg.svg" fill="#22aaee" width="60" />
    </div>
  );
}

这个方案适合不想改动构建配置的场景,但需要处理SVG加载的异步状态。

内容的提问来源于stack exchange,提问作者Noy Oliel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 08:17:41