parcel icon indicating copy to clipboard operation
parcel copied to clipboard

SVG Transformation Removes Definitions

Open mgw854 opened this issue 1 year ago • 5 comments

🐛 bug report

I've included an SVG image using the React component syntax:

import Logo from './Logo.svg';

The SVG has three paths, and one linear gradient defined.

  <defs>
    <linearGradient id="gradient" x1="0.247" y1="0.083" x2="1.011" y2="0.993" gradientUnits="objectBoundingBox">
      <stop offset="0.28" stop-color="#cd163f"/>
      <stop offset="0.9" stop-color="#f58025"/>
    </linearGradient>
  </defs>
  <path id="Path_3788" data-name="Path 3788" d="M8.538,9.3,20.545.4a.222.222,0,0,0-.129-.4H10.568A4.307,4.307,0,0,0,7.53,1.258L1.258,7.523A4.325,4.325,0,0,0,0,10.568v8.864a4.325,4.325,0,0,0,1.258,3.045l6.265,6.265A4.338,4.338,0,0,0,10.568,30h8.523a.222.222,0,0,0,.091-.424L2.25,21.591a2.025,2.025,0,0,1-1.159-1.826v-4.25a1.406,1.406,0,0,1,.568-1.129L4.1,12.576V9.288H8.538Z" fill="url(#gradient)"/>
  <path/>
  <path/>

The first path is filled with the linear gradient, and the other paths are solid colors.

🎛 Configuration (.babelrc, package.json, cli command)

.parcelrc

{
  "extends": "@parcel/config-default",
  "transformers": {
    "*.svg": ["...", "@parcel/transformer-svg-react"]
  }
}

🤔 Expected Behavior

All three paths render, as they do when I open the SVG in the browser by itself.

😯 Current Behavior

Only the last two paths, with solid fill, render. The first path changes its fill property to fill="url('5f5faccf2b6c5172')", but there is no linear gradient definition at all.

💁 Possible Solution

Looks like it might be a similar issue to #8125

🔦 Context

We can't use SVG for our logo unless this is fixed.

💻 Code Sample

  <defs>
    <linearGradient id="gradient" x1="0.247" y1="0.083" x2="1.011" y2="0.993" gradientUnits="objectBoundingBox">
      <stop offset="0.28" stop-color="#cd163f"/>
      <stop offset="0.9" stop-color="#f58025"/>
    </linearGradient>
  </defs>
  <path id="Path_3788" data-name="Path 3788" d="M8.538,9.3,20.545.4a.222.222,0,0,0-.129-.4H10.568A4.307,4.307,0,0,0,7.53,1.258L1.258,7.523A4.325,4.325,0,0,0,0,10.568v8.864a4.325,4.325,0,0,0,1.258,3.045l6.265,6.265A4.338,4.338,0,0,0,10.568,30h8.523a.222.222,0,0,0,.091-.424L2.25,21.591a2.025,2.025,0,0,1-1.159-1.826v-4.25a1.406,1.406,0,0,1,.568-1.129L4.1,12.576V9.288H8.538Z" fill="url(#gradient)"/>

🌍 Your Environment

Software Version(s)
Parcel 2.8.3
Node 18.12.1
npm/Yarn 1.22.19
Operating System Windows 11

mgw854 avatar Feb 22 '23 15:02 mgw854

A workaround would be

{
  "extends": "@parcel/config-default",
  "transformers": {
    "*.svg": ["@parcel/transformer-svg-react"]
  }
}

(as long as you don't have inline styles/actual urls to assets in your SVG)

mischnic avatar Feb 26 '23 10:02 mischnic

Thank you! That workaround helped.

mgw854 avatar Feb 27 '23 15:02 mgw854

Worked for me too. Thanks @mischnic

ViniciusResende avatar Aug 21 '23 14:08 ViniciusResende

I have the same problem, but this workaround didn't fix it for me. I'm guessing it's because my SVG is inlined, and not loaded from an external file.

Edit: I also tried to extract the SVG into an external file and installing the suggested dependency, but it seems like that dependency only works in React projects, so it doesn't work for me.

Edit2: The only workaround I found was using JS to add the element at runtime like .innerHTML = "<svg ..."

belladoreai avatar Sep 02 '23 16:09 belladoreai

A workaround would be

{
  "extends": "@parcel/config-default",
  "transformers": {
    "*.svg": ["@parcel/transformer-svg-react"]
  }
}

(as long as you don't have inline styles/actual urls to assets in your SVG)

@mischnic what should we do if we actually have inline SVGs? We're facing the problem that we include (inline) an SVG with <defs> via posthtml-include and reference their IDs everywhere in the code. This may be the same use case @belladoreai has.

kai-dorschner-twinsity avatar Jan 16 '24 14:01 kai-dorschner-twinsity