A better way to use SVGs
Tags: css, javascript, react, vue
Published: 2021-04-04 09:31:43

---
title: A better way to use SVGs
published: true
description: External SVGs are great, but have obvious downsides when compared to inline SVGs. external-svg-loader solves them by giving a better to use them
tags: css, javascript, react, vue
cover_image: https://cdn.deliciousbrains.com/content/uploads/2019/07/19095418/svgs-for-developers-post-img.jpg
---

It's 2021, and we are still not settled on the best way to SVGs. Inline SVGs offer all the benefits—being able to directly modify fill color, use CSS variables, and modify the inner SVG elements—but have the obvious downside that they make the code messy.

Storing them externally is a better option, but the only reliable way to use them is the &lt;img&gt; tag, which comes with severe limitations. 

```html
<!-- Can't modify the fill color if you want -->
<img src="/path/to/img.svg" />
```

To solve this, I have created a library that offers all the benefits of inline SVGs, while still storing them externally. It's called [svg-loader](https://github.com/shubhamjain/svg-loader).

Check, for example, this logo of [my project](https://svgbox.net) in SVG.

```html
<img src="https://s2.svgbox.net/assets/logo-white.svg" />
```

**Preview**

![](https://s2.svgbox.net/assets/logo-white.svg)

Since the fill color is not defined, it will default to black and there's not much you can do about changing that. There are a few [hacks around this using the filter property](https://stackoverflow.com/questions/42966641/how-to-transform-black-into-any-given-color-using-only-css-filters), but they are complex and not easy to modify. 

In comes, [svg-loader](https://github.com/shubhamjain/svg-loader). You just have to drop the script in and the external SVGs will be fetched and injected inside the element. Like, this:

```html
<script type="text/javascript" src="https://unpkg.com/external-svg-loader@1.0.0/svg-loader.min.js" async></script>
  
<div style="display:flex;">
    <div style="background:black;">
        <svg data-src="https://s2.svgbox.net/assets/logo-white.svg" fill="yellow"></svg>
    </div>
    <div style="background:purple;">
        <svg data-src="https://s2.svgbox.net/assets/logo-white.svg" fill="white"></svg>
    </div>
    <div style="background:green;">
        <svg data-src="https://s2.svgbox.net/assets/logo-white.svg" fill="white"></svg>
    </div>
</div>
```

**Preview**

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wqxcuvve6ha4hm0betvr.png)

**[View on JS Fiddle](https://jsfiddle.net/ofd58uve/)**

The library is very light <2KB (post-compression). The loads are lightning fast and also comes with a way to cache the file for longer. So, the image isn't fetched repeatedly. And pretty much works anywhere.

## Compatible with React, Vue, Angular
svg-loader is framework agnostic and works with most front-end frameworks. You just need to include the library somewhere and everything else will be handled:

```jsx
import React from 'react'
import ReactDOM from 'react-dom'

import 'external-svg-loader';

class App extends React.Component {
  render () {
    return (
      <svg
        data-src="https://s2.svgbox.net/materialui.svg?ic=mail"
        fill="currentColor"
        width="50px"
        height="50px"
        style={{
          color: 'red'
        }}
      />
    )
  }
}

ReactDOM.render(
  <App />,
  document.getElementById('container')
);
```

[**View on Codesandbox**](https://codesandbox.io/s/react-playground-forked-x7w1l?file=/index.js)


**Note**: The resources need to be compatible with the [CORS policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) since XHR is used to fetch them.

Thoughts? Questions? Feel free to reply here.