34 comments

[ 5.0 ms ] story [ 41.5 ms ] thread
Amazing.
HN is really aware of these type of comments. An account created 47 minutes ago. A single comment on this post.
This does exactly what I have been doing manually for at least ~15 times in the last week. If only I saw this a few weeks ago.. (It's easy / not lot of work, but why if we can automate?)
Let's not forget, sometimes when you need some really basic functionality, you don't have to reach for a module that maybe does a lot more than what you need. For example, the last time I needed svg inlined into a web app I was working on, this is the quick component that I whipped up:

https://gist.github.com/ajbdev/8d15e302564fe04a7d383c1a54f8d...

Despite it's simplicity, it has yet to fail me.

besides - if you generate your SVG programmatically you can just return them in your render function:

function Foo(props) { return <svg> <circle cx="10" cy="10" r="100" /> </svg> }

Good reminder, simpler is better
(comment deleted)
This is doing little more than providing a wrapper around svgo, which is doing all the real work.

This is generally a poor use of SVG as well, if your use of SVG is for static assets, don't transform all your SVG into react, leave it as SVG where it can be easily manipulated and editing by the plethora of tools that can work directly with SVG, previewed in the browser, etc. If you need you can inline the SVG into your CSS via a base64 URI, etc.

Ideally this is applied as a webpack transform, so the asset is left as SVG, and only converted during the build process.

Inlining the SVG as Base 64 in CSS is not that good, since it limits what you can do with it (basically setting it as a background). If you create an actual SVG tag within HTML (via React) you can then use CSS to style the strokes, fills, etc.

Base64-encoded SVGs have a terrible impact on performance on mobile, so I'd be careful with that. Saying that, the situation has improved in the past few years (mostly because of hardware, not browser optimisations afair)
I love adding my svg as react components, actually. It makes it easy to conditionally toggle parts of it, change text, manage colors, etc.

Of course, if you just want to use the svg doc as a static icon, then yes by all mean, a plain file will do. But given the (very small) size of a svg file, caching it as a single resource may not be that useful.

agree most people who do inline styles (or any form of "my styling is written in the react file") do this afair

we inline for the same reason

i hope someone writes a good precompiler that allows efficient using def/use for (non changed) static inlining http://www.svgbasics.com/defs.html

Umm, you should be doing that with CSS. Basically what this means is whenever your application code changes, it busts the cache on all your SVG assets if you use this method.

The only use-case for using SVG with something like react is for data visualization where you are programmatically building up and updating a SVG DOM based on some data.

A good example of this is a flow-chart graph/tree UI done in SVG that is generated from a nested data structure. Its unlikely these elements would be expressed as static assets in the first place.

Even still I would be cautious in using SVG in this way for all but the least trivial things, as react has been optimized to diff HTML structures, not SVG. I'd like to see, for example, how it handles SVG cascade transforms for instance. Its usually not efficient to alter the SVG DOM by inserting/removing nodes, because the layout rules and semantics of SVG is different than HTML.

(comment deleted)
>This is generally a poor use of SVG as well, if your use of SVG is for static assets, don't transform all your SVG into react, leave it as SVG where it can be easily manipulated and editing by the plethora of tools that can work directly with SVG, previewed in the browser, etc. If you need you can inline the SVG into your CSS via a base64 URI, etc.

As valid as this seems on the surface, why can't transforming SVG into React be a build step where React is an intermediate artifact?

The webpack option for this seems ideal for that even... I'd be far more interested in that than pre-transform steps.
"Your scientists were so preoccupied with whether or not they could, they didn’t stop to think if they should."
If I can have only one question, it would no doubt be “why”?
We do this at my work - it allows easy programmatic inclusion.

We wouldn’t do it if browsers weren’t a buggy mess with the USE tag though (Chrome in particular is a dumpster fire of SVG bugs).

Yeah, USE tag is pretty buggy across browsers.

Also, sometime you just need to inline SVG, for example if you want some icon path fill color to change on mouse-over. Easy with inline SVG and CSS rule. Can't really do that (well) with external .svg.

We actually had a nice system for that... but again: browser bugs :(

Until browsers collectively get off their asses with SVG (most of these bugs are years old in their big trackers) using React for SVGs is a good workaround.

They won't because it seems like they might as well forge ahead with CSS additions and drop an entirely separate renderer. That's what happened to the SVG Animations.

Of course it's not like svg will get removed so Why fight it...

It seems they stop work as soon as a feature hits SVG - CSS Animation, Canvas, WebGL... all have open SVG bugs. Some years old.
> Easy with inline SVG and CSS rule. Can't really do that (well) with external .svg.

I can see that easily solved much better, cleanly and not to mention lightweight with some CSS rather simple pre-processors in the build process.

Or is your argument that you already have a (React-based) build-process and you'd want to align this with what you have, rather than creating something new and different along-side everything else (despite the result being suboptimal)?

We use SVG as react components to change SVG attributes without the need to change the SVG source, e.g. the color of the icons etc
You know you can use CSS and JS for that?
How would I go to represent rectangles, circles, text and lines with CSS and JavaScript? With Canvas? Is React able to render to canvas?

Sometimes SVG is a good fit for the graphics needed.

I meant styling the SVG — instead of replacing SVG with react (slow), use CSS to modify properties of the SVG DOM.

That is significantly faster.

> You know you can use CSS and JS for that?

No, I didn't. Thanks. /s

There are many cases it's more convenient updating SVG using React.

Of course it is more convenient, but it's also several orders of magnitude slower.

If you try rendering, say, maps with SVG, this becomes a significant issue.

Doesn't `react-svg-loader`[0] do the same?

[0] https://github.com/boopathi/react-svg-loader

I'd done this awhile ago with https://github.com/ryanmcgrath/react-iconpack (haven't touched it in literally forever, at least insofar as time is considered in the JavaScript world - probably doesn't work now), too. Never caught on for whatever reason, but was fun to hack together.

I do feel like (and I think another commenter somewhere in here noted this) that actually fully converting SVGs to JS has a lot of detriments in terms of ability to edit and such, so the loader approach is better.

Another approach which I use at work is to use `postcss-inline-svg`[0]. This allows you to "import' the SVG from your CSS and then customize it. For example, you might want the icon in a different color:

    background: svg-load('myicon.svg', fill=blue);
The SVG would then be inlined into the CSS instead of the HTML.

[0] https://github.com/TrySound/postcss-inline-svg

Super cool to see other people using this pattern! People here are bringing up great points about the implications of this pattern. Our motivation to use this pattern was when replacing grunticon generating multiple colors of our SVGs during a build step. The grunticon step added a 1min+ to the feedback loop on seeing CSS changes(could have fixed this directly, lots of missed details in this story).

This simple script allowed us to quickly move past the problem during a rewrite to React, and solve more correctly when that system was a priority. https://gitlab.com/gjjones/svg-to-react