Home > Software design >  Import svg as component using preact and vite
Import svg as component using preact and vite

Time:09-27

I'm currently working on an application using preact, tailwindcss and vite. Unfortunately, importing svgs seems to be a bit problematic. There is a separate repository that only contains the svg resources. My original plan was to just import them as components as I was used to do it in classic react with webpack applications using SVGR and the following syntax:

import { ReactComponent as Search } from 'assets/icons/search-lg.svg';

This won't work for (at least) two reasons. One being preact the other one being the lack of SVGR. I then proceeded to give vite-plugin-svgr a try by importing it in my vite.config.js.

  plugins: [svgr({ svgrOptions: { jsxRuntime: 'classic-preact' } }), preact(), tsconfigPaths()],

It kinda works using the following import syntax:

import Search from 'assets/icons/search-lg.svg?component';

Unfortunately this raises the following error which I couldn't manage to work around besides ignoring it which is not really an option:

TS2307: Cannot find module 'assets/icons/search-lg.svg?component' or its corresponding type declarations

The alternate plan would now be to create a wrapper component that just imports the svg from the given path and create a component from it myself. This would also simplify styling it with tailwind. Unfortunately I fail to import the file in a way I can wrap it with <svg> tags. Using <img> is not really an option because I need to be able to manipulate the svg.

So, does anybody have an idea how to either

  • correctly use the component import in my setup
  • create a preact component that imports an svg from a file and still is customizable

Thanks in advance!

CodePudding user response:

I finally got it to work by using vite-plugin-svgr. In the end adding /// <reference types="vite-plugin-svgr/client" /> to vite-env.d.ts made the compiler happy.

I can now use the good 'ol syntax:

import { ReactComponent as Search } from 'assets/icons/search-lg.svg';

Thanks to @user-28 for pointing me in the right direction!

  • Related