DEV Community

Cover image for Dynamic SVG component in Vite + React + TS

Dynamic SVG component in Vite + React + TS

Amit Mondal on September 07, 2022

After hearing many amazing things about vite I decided to try it and create something and I am not at all disappointed with the DX. So when I was d...
Collapse
 
hazemalabiad profile image
Hazem Alabiad •

Amazing!
I really appreciate you :)

I have a question why this solution does not work when we use useState instead of useRef?

Collapse
 
mondal10 profile image
Amit Mondal • • Edited

Sorry for late comment.

A small note for anyone who tries useState instead of useRef: React treats a function passed to a setter as an updater, so setSvgIcon(ReactComponent) will call the component instead of storing it. Wrap it in an arrow function to fix it:

setSvgIcon(() => ReactComponent);
Enter fullscreen mode Exit fullscreen mode

useRef skips this because assigning to ref.current is a plain assignment.

Also, if you’re on vite-plugin-svgr v4+, import with ?react and use the default export instead of ReactComponent.

Collapse
 
jradams1997 profile image
Justin Adams •

The author isn't going to answer questions because he doesn't know. He just stole the code from: StackOverflow without crediting the author. Shameful.

Collapse
 
njavilas2015 profile image
njavilas2015 •

great article!

Collapse
 
feralvarz profile image
feralvarz •

Thanks for sharing, great article.

Collapse
 
dopamine0 profile image
Roee Fl •

Thank you @mondal10, so helpful, you really rescued me in despair.

Collapse
 
philmander profile image
Phil Mander •

Thanks @mondal10. Very helpful!

Collapse
 
dopamine0 profile image
Roee Fl •

Lmao @jradams1997 pwned

Collapse
 
jradams1997 profile image
Justin Adams •

Did I say anywhere in my comment that it was my code? Also, I know it’s probably too hard for you, but you can press the ‘Reply’ button to directly reply. Have a nice day.

Collapse
 
dopamine0 profile image
Roee Fl •

Toxic mate

Collapse
 
abdullohzenbit profile image
Abdulloh •

How it influence bundle size ?

Collapse
 
mondal10 profile image
Amit Mondal •

It’s a mixed bag, but mostly good.

Pros:

  • Vite (Rollup) sees import(../../assets/icons/${iconName}.svg) and splits every SVG in that folder into its own chunk. None of them land in the main bundle, so the initial load stays small.
  • An icon is only downloaded when it’s first rendered, then cached.

Cons:

  • Since the name is dynamic, Vite can’t tell which icons you use, so all icons in that folder get built as chunks, even unused ones. Build output grows, but users only download what they render.
  • Each icon is a separate request, so a page with many different icons means many small requests (and a brief shimmer on first load).
  • Each chunk is a React component (JS), so it’s slightly larger than the raw .svg.

Tip: for icons shown on every page (logo, nav), import them statically so they ship in the main bundle and don’t flash a loader. Keep the dynamic folder limited to icons that really are on-demand.