25

Using babel-plugin-inline-react-svg from within my next.js app, I'm importing some SVGs into my React v16.0.0 component like so.

import React from 'react';
import Close from './close.svg';
import Chevron from './right.svg';
import EmptyCart from './empty.svg';

const Component = props => (
  <div>
    <Close />
    <EmptyCart />
    <Chevron />
  </div>
);

When I run that code, the page is rendered with the 3 SVGs all being the same, like this:

duplicated SVGs

Whichever of the SVGs I render first seems to take over all of the other ones. If I put <EmptyCart /> first, they'll all be cart icons. But here's the real kicker: When I inspect the DOM, the SVGs seem to all be correct (they're all completely different from each other).

Anyone seen this before? How is this even possible for the DOM to say one thing but the browser to render another thing?

dargue3
  • 2,802
  • 2
  • 14
  • 23

8 Answers8

35

It would be helpful to see the other SVGs as well, but if they are similar and the id's match, then this is your problem.

    <path id="4eeded6c-befb-41ba-a055-83a9e4ddc009" d="M3.632 3.182H1.091A1.09 1.09 0 0 1 1.09 1h3.322c.467 0 .883.297 1.033.74l4.096 12.046.036.134c.083.406.53.777.928.78l8.87.056c.39.002.831-.361.925-.816l1.552-6.017a1.09 1.09 0 1 1 2.112.545l-1.539 5.96c-.285 1.417-1.625 2.518-3.064 2.51l-8.869-.057c-1.408-.008-2.718-1.073-3.036-2.451L3.632 3.182zM9.272 23a2.191 2.191 0 0 1-2.181-2.201c0-1.216.977-2.2 2.182-2.2s2.181.984 2.181 2.2A2.191 2.191 0 0 1 9.273 23zm10.91 0A2.191 2.191 0 0 1 18 20.799c0-1.216.977-2.2 2.182-2.2s2.181.984 2.181 2.2A2.191 2.191 0 0 1 20.182 23z"/>

You can see that this id get's targetted and reused within the SVG itself here:

    <use xlink:href="#4eeded6c-befb-41ba-a055-83a9e4ddc009"/>

This is a common problem, especially when exporting from apps like photoshop etc. To avoid conflicts when i use svg's I manually change all id's to ensure uniqueness.

If it helps, I've created a code-pen which goes into more examples of how to re-use svg's : https://codepen.io/peter-mouland/pen/JErvZY

peter.mouland
  • 1,893
  • 17
  • 30
5

The issue can be related to the non-unique ids in SVGs.

It is common that svg generators can return content with the same Ids like <mask id="mask0" /> which then is referenced by <g mask="url(#mask0)"/>.

In case you have two different SVGs with the same mask id you will likely to have an issue with rendering two different icons.

The simplest solution is to specify a unique id for each <mask /> and then don't forget to update the reference in <g />.

Pavlo Hryza
  • 627
  • 1
  • 11
  • 18
  • 1
    This fixed it in my case. If you're exporting from Figma you'll find your `` elements to have this matching ID and render each SVG the same across your entire app. This was true for me outside of React. – s0rfi949 Sep 01 '19 at 22:59
  • @s0rfi949 how did you solve your figma problem, we can't find where in figma to declare mask ids – Daniel Birowsky Popeski Dec 21 '20 at 18:08
  • @DanielBirowskyPopeski sorry it's been a long time and I don't remember exactly. But I think it is found in Export Options or see this post: https://www.figma.com/blog/with-figmas-new-svg-exports-less-more/ – s0rfi949 Dec 22 '20 at 16:00
4

You should to assign different id to each svg icon in your config file. Like this:

// SVG are imported as react components
  {
    test: /\.svg$/,
    use: [
      {
        loader: 'babel-loader',
      },
      {
        loader: 'react-svg-loader',
        options: {
          svgo: {
            plugins: [
              {
                removeTitle: true,
              },
              {cleanupIDs: {
                  prefix: {
                      toString() {
                          this.counter = this.counter || 0;

                          return `id-${this.counter++}`;
                      }
                  }
              }},
            ],
            floatPrecision: 3,
          },
        },
      },
    ],
    include: paths.svg,
  },
Sergio
  • 41
  • 2
4

I also had a similar issue because i exported images from Figma and i was using them on a project.

So each time i include the other SVG as a component it will override one of the SVG and show the first one.

After a careful check, i noticed that they were actually having the same id and the same image name

having the fill attribute point to the pattern45550 which is my new svg name in my case

<rect width="48" height="52" fill="url(#pattern45550)"/>

renaming the id to pattern45550

<pattern id="pattern45550" patternContentUnits="objectBoundingBox" width="1" height="1">

renaming the image name image10000000 also in the below tag

<image id="image10000000" width="2887" height="3162" xlink:href="data:image/png;base64...

then lastly point the URL to image10000000 image

<use xlink:href="#image10000000" transform="translate(0 -0.00550212) scale(0.00034638)"/>

and it all worked well in my case.

Nazehs
  • 478
  • 1
  • 10
  • 19
2

In my case, the conflict between both SVG was because internally they have the same .className

Two solutions:

  • Change the intern class name in one of them

  • If it is possible (for example if you are using CRA) load one of the svg using <img src'file.svg'>

Juanma Menendez
  • 17,253
  • 7
  • 59
  • 56
1

In some Case we define styles of our SVG like this


<svg>
   <defs>
        <style>.a{fill:none;}</style>
   </defs>
</svg>


here we define a class name style as .a, in my project all of svgs use the same class name and if I use more than one SVG in DOM then my svgs styles are overwrite and break the design

solution: you should change classname to avoid duplicated class name

hamidreza nikoonia
  • 2,007
  • 20
  • 28
1

I encountered this issue when I try to use multiple svgs downloaded from a figma file on a screen, the other svg override the other. The issue was the class name in each svg was similar. So I edited the class name to prevent them from clashing

0

The problem is most likely that the IDs are not unique between the SVGs, as has been mentioned above. There are some loaders which can handle this problem for you automatically, so that you don't have to manually change all of the IDs and references to them. Check this out: https://github.com/SilverFox70/svg-react-loader