npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

external-svg-loader

v1.7.1

Published

Plug 'n play external SVG loader

Downloads

64,279

Readme

SVG Loader

NPM minified size gzip size

SVGs from an external source can be rendered with <img> tags, but this has multiple drawbacks: you can't customize the fill or stroke colors, use CSS variables, or use focus/hover states.

SVG Loader is a simple JS library that fetches SVGs using XHR and injects the SVG code in the tag's place. This lets you use externally stored SVGs (e.g, on CDN) just like inline SVGs.

It's super-tiny, works with all frameworks, requires no additional code except the initial script load, and has minimal to no impact on performance.

Demo →

How to Use?

SVG Loader is designed to be plug and play. Hence, all you need to is to include the loader JS anywhere in your code, and then start using the code like this:

Download and Include

<!-- 
    Include this script anywhere in your code, preferably <HEAD> so
    icons can be fetched faster.
-->
<script type="text/javascript" src="svg-loader.min.js" async></script>

<!-- Use an external SVG -->
<svg
  data-src="https://unpkg.com/@mdi/[email protected]/svg/star.svg"
  width="50"
  height="50"
  fill="red"></svg>
<svg
  data-src="https://unpkg.com/@mdi/[email protected]/svg/heart.svg"
  width="50"
  height="50"
  fill="red"></svg>

<svg
  data-src="https://unpkg.com/@mdi/[email protected]/svg/cog.svg"
  width="50"
  height="50"
  fill="currentColor"
  style="color: purple;"></svg>

See Here →

Note: Because SVG Loader fetches file using XHRs, it's limited by CORS policies of the browser. So you need to ensure that correct Access-Control-Allow-Origin headers are sent with the file being served or that the files are hosted on your own domain.

Or, use from the npm package

The library is framework/platform agnostic. You should be able to use it in React, Vue.js and others as long as you're using the correct attributes.

npm install external-svg-loader

Then, in your app, require/import external-svg-loader anywhere. Here's an example:

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"));

See Here →

Or, use a CDN

SVG loader can also be included via unpkg CDN. Example:

<script
    type="text/javascript"
    src="https://unpkg.com/external-svg-loader@latest/svg-loader.min.js"
    async></script>

Configuration

1. Disable/Modify Caching

By default, the XHR response is cached for 30 days, so that any subsequent loads are instantenous. You can disable this behavior by passing data-cache="disabled".

You can destroy the currently stored cache by calling:

SVGLoader.destroyCache();

You can also modify the caching period by passing number of seconds. Example:

Cache for a week

<svg
  data-src="https://unpkg.com/@mdi/[email protected]/svg/heart.svg"
  data-cache="604800"
  width="50"
  height="50"></svg>

Cache for a six hours

<svg
  data-src="https://unpkg.com/@mdi/[email protected]/svg/heart.svg"
  data-cache="21600"
  width="50"
  height="50"></svg>

Disable Caching

<svg
  data-src="https://unpkg.com/@mdi/[email protected]/svg/heart.svg"
  data-cache="disabled"
  width="50"
  height="50"></svg>

2. Enable Javascript

SVG format supports scripting. However, for security reasons, svg-loader will strip all JS code before injecting the SVG file. You can enable it by:

<svg
  data-src="https://unpkg.com/@mdi/[email protected]/svg/heart.svg"
  data-js="enabled"
  onclick="alert('clicked')"
  width="50"
  height="50"
  fill="red"></svg>

3. Disable Unique IDs, Styling

To prevent conflicts between conflicting identifiers of different SVGs, svg-loader scopes the identifiers and styling rules by adding prefixes.

You can disable this behavior by:

Disable Unique IDs

<svg
  data-src="https://unpkg.com/@mdi/[email protected]/svg/heart.svg"
  data-unique-ids="disabled"
  width="50"
  height="50"
  fill="red"></svg>

Disable CSS Scoping

<svg
  data-src="https://unpkg.com/@mdi/[email protected]/svg/heart.svg"
  data-css-scoping="disabled"
  width="50"
  height="50"
  fill="red"></svg>

Lazy Loading

You can also lazy load icons by using data-loading=lazy. This will make icon not load until it's about to enter the viewport. For lazy loading, external-svg-loader uses Intersection Observer API.

<svg
  data-src="https://unpkg.com/@mdi/[email protected]/svg/heart.svg"
  data-loading="lazy"
  width="50"
  height="50"></svg>

Event

When the SVG has been loaded an event iconload is triggered. This can be used to get the references to the loaded SVG element and do some further processing. You can also use the oniconload inline function.

Using oniconload inline function

<svg
  data-src="https://unpkg.com/@mdi/[email protected]/svg/cog.svg"
  oniconload="console.log('Icon loaded', this)"></svg>

Using addEventListener

<svg data-src="https://unpkg.com/@mdi/[email protected]/svg/cog.svg"></svg>

<script>
  window.addEventListener('iconload', (e) => {
      if (e.target.id === 'iconload') {
        console.log('Icon loaded', e.target);
      }
  });
</script>

Using the iconloaderror event

When an error occurs during loading of the SVG file, an iconloaderror event is triggered, passing the error message as the event's detail.

<svg data-src="https://unpkg.com/@mdi/[email protected]/svg/this-svg-does-not-exist.svg"></svg>

<script>
  window.addEventListener('iconloaderror', (e) => {
    console.error('Failed to load SVG:', e.detail);
  });
</script>

Similarly to the iconload event, iconloaderror can also be used with an inline function, which will have access to an error argument (the Error object that was thrown):

<svg
  data-src="https://unpkg.com/@mdi/[email protected]/svg/cog.svg"
  oniconloaderror="console.log('Error loading SVG:', error.toString())"></svg>

Using Events in React

React doesn't support custom events out of the box. To circumvent this limitation, you can use refs.

class MyApp extends React.Component {
  constructor(props) {
    super(props);
    this.ref = React.createRef()
  }
  render() {
    return (<svg data-src="https://unpkg.com/@mdi/[email protected]/svg/cog.svg" ref={this.ref}></svg>);
  }
  componentDidMount() {
    this.ref.current.addEventListener('iconload', () => {
      console.log("Icon Loaded", this.ref.current)
    });
    this.ref.current.addEventListener('iconloaderror', (e) => {
      console.error('Failed to load SVG:', e.detail);
    });
  }
}

LICENSE

MIT