Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 924
dargue3 Avatar asked Nov 17 '17 20:11

dargue3


People also ask

Can I use SVG as background image react?

The SVG image format can be used as a background image in the same way as the PNG, JPEG, and GIF image format.

Which SVG attributes are supported by react?

SVG is well-supported in modern browsers, including Firefox, Safari, Chrome, and Edge. All of these support embedding SVG directly in HTML, and React supports using SVG elements to build your components.


2 Answers

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

like image 51
peter.mouland Avatar answered Sep 30 '22 11:09

peter.mouland


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,
  },
like image 20
Sergio Avatar answered Sep 30 '22 12:09

Sergio