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



Solution 1:[1]

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.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1