What is the best way to use custom svg icons in Reagent?

I’ve been learning ClojureScirpt for about a month. I figured out lots of things but there is one question bothering me, which is how to use svgs in Reagent. In webpack, there are some loaders can transform svgs to React component, such as “react-svg-loader”, “svg-react-loader”, “svgr”, and so on. Most of these loaders are also able to use svgo to optimize svg files at build time. But how do you normally do it in Reagent projects? I mean, use custom svgs, not some third party icons set.

I also have some thoughts:

  1. Can shadow-cljs work together with webpack or rollup? So I can benefit from the svg loaders, let the webpack loader to transform svgs to React component, and use them in Reagent.
  2. Writing some scripts to convert the svg files to hiccup syntax?

Could you give me some hints? Thanks!

1 Like

Hi,

AFAIK you can’t import a SVG file like you would in the Webpack world, because the ClojureScript compiler doesn’t support that and Webpack is the last step. I’m quite a noobie myself, so I might be wrong.

What I’ve been doing is the following: I add a SVG sprite to the bottom of my HTML template, like described here: https://css-tricks.com/svg-sprites-use-better-icon-fonts/

<svg>
  <defs>
    <g id="icon-foo">
      <!-- all the paths and shapes and whatnot for this icon -->
    <g>
    <g id="icon-bar">
      <!-- all the paths and shapes and whatnot for this icon -->
    <g>
    <!-- etc -->
  </defs>
</svg>

And then in my Reagent components (this one was tricky because of a React limitation, the upper/lower case is very important here):

(defn svg-icon [id]
  [:svg {:class "icon"} [:use {:xlinkHref (str "#icon-" id)}]])

And then inside a component:

[svg-icon "foo"]

This of course doesn’t process the icons with svgo or the likes, but if you serve the HTML template with something like Ring, you could load up and process the SVG icons yourself.

Hope that helps,
Manu

2 Likes