dargue3
dargue3

Reputation: 2922

React rendering SVG overwrites other SVGs on the page

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?

Upvotes: 26

Views: 16063

Answers (8)

Bamgboye Ibukunoluwa
Bamgboye Ibukunoluwa

Reputation: 21

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

Upvotes: 1

Nazehs
Nazehs

Reputation: 558

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.

Upvotes: 5

hamidreza nikoonia
hamidreza nikoonia

Reputation: 2165

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

Upvotes: 1

Juanma Menendez
Juanma Menendez

Reputation: 20129

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'>

Upvotes: 2

Pavlo Hryza
Pavlo Hryza

Reputation: 667

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 />.

Upvotes: 6

WFBrinkert
WFBrinkert

Reputation: 11

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

Upvotes: 0

Sergio
Sergio

Reputation: 41

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,
  },

Upvotes: 4

peter.mouland
peter.mouland

Reputation: 1983

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

Upvotes: 37

Related Questions