The web has come a long way in the past years, but there are still things that aren't straightforward. Using icons is one of them.
Icon fonts, inline SVGs, SVG Symbols—all have their own issues. Inline SVGs are great, for example, but they make the code messy, and can't be cached. Additionally, copy-pasting the SVG itself is pretty time-consuming and a PITA.
Using icons should be simpler. Here's what I always wanted: I see an icon I want to use and I am able to use it right away. No copy-paste; only have to know the name of the icon. No struggling to make the Webpack/Grunt pipeline work. No creating a new SVG file/component for every icon I want to use.
Luckily, I have found a way. Follow along!
svg-loader: Load SVGs from a CDN
svg-loader is a simple library that allows you to inline SVGs hosted on an external source. Here's a more detailed article I wrote about it, but to put it simply, you use it this way:
<script type="text/javascript" src="https://unpkg.com/external-svg-loader@1.0.0/svg-loader.min.js" async></script>
<svg data-src="https://s2.svgbox.net/assets/logo-white.svg"
width="50"
height="50"
fill="purple"></svg>
The library will fetch the SVG using XHR and inject it inline. The benefit? You can now customize the fill, inherit the colors, and use states like hover, which wouldn't have been possible with <img>
and <object>
tags.
The concept isn't new as svg-inject does something similar. However, svg-loader makes this ultra-convenient. You only have to worry about including the script somewhere in the code. Rest everything is handled. And it's framework-agnostic, too (works with React/Vue/Angular...).
svg-loader + unpkg = killer combo
Recently, I discovered that I can use the library and unpkg to quickly include an icon available on Github.
Take, for instance, MDI repository. To my knowledge, it's the most extensive icon repository on Github that has 5k+ icons.
Since the repo has an NPM package, we can browse it on unpkg: https://unpkg.com/@mdi/svg/.
If you click any file and use "View Raw" you'll see that the permalink to any icon is something like this: https://unpkg.com/@mdi/svg@5.9.55/svg/__ICON__.svg
.
We can use this to start using the icon in our project. Example:
Hurray! Now, if you need to use the cog
icon, you don't have to hunt for the SVG code, or download it, you can just use cog.svg
.
Note: The first load can have a slight delay because Unpkg fetches the package and extracts the file, but after the first request, the file is cached and served from Cloudflare CDN.
Q&A About this Approach
There might fair amount of questions about this approach, so I will try to answer the most common of them.
What if there are changes in the repo (like, renaming files)? Won't it break my icons?
No. With unpkg, you'll most likely be using versioned URLs (instead of @latest
), which will make sure that the contents remain the same regardless of changes in the repository.
Isn't it inefficient to fire XHR for every icon, instead of bundling them?
No. With HTTP2, the cost of making is incredibly low. For non-blocking resources loaded asynchronously, it's almost irrelevant. Here is me loading 50 icons using the same approach.
Besides, the icons are also cached when loaded first-time, so the subsequent loads are incredibly fast.
What if unpkg goes away?
It won't. It's a project supported officially by Cloudflare and serves 3B+ requests per day.
What if I want to use an icon set that doesn't have an npm package?
You can use jsDeliver that has a similar API and supports raw Github repos as well.
I feel this is a pretty nifty approach for icons. You can use icons from Font Awesome, Octicons, or any of the awesome icon sets hosted on Github.
It's fast, very reliable, and keeps the code clean.
Top comments (3)
Https://iconmeister.github.io has 7300 icons and bundles only used icons in one file
Interesting approach to age-old problem. Nice 👌
Thanks for sharing! I’ll definitely try this.