12

I'm having a lot of trouble working with SVG in my webpack workflow. I'm trying to get it to display with the background: url(sample.svg) property in CSS. Using this alone did not work, so I figured I had use a loader. Here are the steps I used.

I used svg-url-loader to load the SVG.

1. I installed svg-url-loader via npm and added this to my module.exports:

 {
        test: /\.svg/,
        use: {
            loader: 'svg-url-loader'
        }
      },

2. I added this to the top of my index.js file:

require('svg-url-loader!./images/topography.svg');

3. I added background-image with the SVG path to my CSS:

body {
  background-image: url("../images/topography.svg");
  background-size: 340px, auto;
  min-height: calc(100vh - 100px);
  margin: 50px;
  background-attachment: fixed;
  letter-spacing: -1px;
}

4. The SVG is not being rendered to the page. When I inspect the body in browser, I find this:

background: url(data:image/svg+xml,module.exports = __webpack_public_path__ + '8dccca4….svg';);

I don't know too much about data-uri, so maybe I am running into the issue there.

Also, I've tried this using different SVG files, and none of them worked.

InspectorDanno
  • 935
  • 2
  • 12
  • 23

4 Answers4

5

I met the same exact error. After some investigation I found I added another svg loader which caused this problem, so I fixed it by deleting the other svg loader:

      {
        test: /\.svg/,
        use: {
            loader: 'svg-url-loader'
        }
      },

      {
        test: /\.svg$/,
        use: [
          "babel-loader",
          {
            loader: "react-svg-loader",
            options: {
              svgo: {
                plugins: [{ removeTitle: false }],
                floatPrecision: 2
              },
              jsx: true
            }
          }
        ]
      }

So you maybe also added some extra loaders to handle the svg files at the same time, please check.

Jeff Tian
  • 5,210
  • 3
  • 51
  • 71
2

You can:

a) set up loaders in webpack.config.js:

example.js:

import ExampleIcon from 'assets/icons/example-icon.svg';

...

<ExampleIcon className={styles.exampleIcon} />

webpack.config.js:

{
  test: /\.svg$/,
  use: [
    {
      loader: 'babel-loader',
    },
    {
      loader: 'react-svg-loader',
      options: {
        svgo: {
          plugins: [{ removeTitle: false }],
          floatPrecision: 2
        },
        jsx: true
      }
    }
  ]
},

b) or set up loaders in the import string:

import ExampleIcon from '!babel-loader!react-svg-loader!assets/icons/example-icon.svg';

...

<ExampleIcon className={styles.exampleIcon} />

Ukr
  • 2,411
  • 18
  • 16
0

I met the same problem too. We have a custom url-loader which is based on url-loader and file-loader. When the size of svg is limited to 10Kb, it will call the url-loader to process the svg,otherwise it will call the file-loader to process. It seems ok,but the bundled file shows that it was processed twice by different loaders. The base64 encoded string was exported through module.exports, but in the page the path was not replaced. This is because I used vue-cli to create project, and the svg was processed by the file-loader. When I deleted the default configuration of file-loader, it worked as expected.

inchill
  • 1
  • 1
0

I had the same problem as you. Updating my file-loader from 2.x.x to the latest version fixed the issue.

Daan Seuntjens
  • 880
  • 1
  • 18
  • 37
Cheeto
  • 1
  • 1