Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you use an SVG inline in React using Parcel 2?

Previously in Parcel v1 you could just use something like the @svgr/parcel-plugin-svgr plugin for Parcel. This would give you the ability to use SVGs inline like when using CRA:

import Star from './star.svg'

const App = () => (
  <div>
    <Star />
  </div>
)

Can anyone help figure out a way to do this in Parcel 2?

like image 375
JosephScript Avatar asked May 21 '20 22:05

JosephScript


People also ask

What is SVGR?

A complete tool box to take advantage of using SVGs in your React applications. Browse GitHub.


1 Answers

Parcel2 provides the @parcel/transformer-svg-react plugin to accomplish this.

Here's what you need to do:

  1. Install it:

    yarn add @parcel/transformer-svg-react --dev
    
  2. Add a .parcelrc file at the root of your project that defines a named pipleine that uses this plugin:

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

    (The "..." entry should actually be typed into the .parcelrc file - it tells parcel "process these kinds of assets as usual, and only after you are done, transform it into a react component.")

    Update (5/2022) I added the "jsx:*": ["..."] line, which appears to currently be a necessary workaround to avoid this bug.

    Another current "gotcha" is that if the SVG files that you want to transform into react components contain inline style tags (e.g. <path style="fill:red" ...>, you'll run into this bug. To avoid it, you'll want to remove the @parcel/transformer-svg plugin from your pipeline by modifiying the first transformer line to read "jsx:*.svg": ["@parcel/transformer-svg-react"] (i.e. remove the ...).

  3. Use the named pipeline in your import statements:

    import Star from 'jsx:./star.svg'
    
    const App = () => (
      <div>
        <Star />
      </div>
    )
    
  4. (optional, if you use TypeScript). Let TypeScript know about the jsx: named pipeline by using a wildcard module declaration. In a d.ts file that's a part of your typescript project, write this:

    declare module "jsx:*.svg" {
      import { ComponentType, SVGProps } from "react";
      const SVGComponent: ComponentType<SVGProps<SVGSVGElement>>;
      export default SVGComponent;
    }
    

See parcel 2 documentation.

like image 186
Andrew Stegmaier Avatar answered Oct 07 '22 17:10

Andrew Stegmaier