External SVG use in Storybook (Angular)

Today I came across the issue to implement externally stored SVG icons in my Angular Storybook — here’s my solution.

When working with Design Systems or Component Libraries it’s not uncommon to use SVG icons that are stored externally.

To use external SVG icons, the HTML code usually is:

<svg aria-hidden=”true”>
<use xlink:href=”external-icons.svg#myIconID”></use>
</svg>

When opening your HTML in the browser, the console might throw an error similar to this one:

Storybook

For Storybook there’s a different project setup: Stories are rendered inside an iframe which means that the external SVG url must be callable from the inside.

Stories for an Angular project usually consists of code like this:

('Key Visual Component', module)
.add(
'With Headline',
() => ({
component: KeyVisualComponent,
props: {
image: text('Images', 'myImage.png'),
headline: text('Headline', 'This is a headline'),
}
});

In the HTML there are now external SVGs used like the code snippet before. So, how to get rid of this error message?

svg4everybody

It’s a common workaround to use a kind of a polyfill to make the SVGs available. The most popular one might be svg4everybody.

For this case here, the component should not implement the JavaScript to keep it clean. The surrounding app should implement polyfills like this.

Where to put the polyfill now for Storybook?

Within the storybook configuration there’s an option to create an html file called . All content from this file will be rendered into the iframe of your story.
So the svg4everybody JavaScript needs to be loaded (whether it’s from a CDN or local file it doesn’t matter).

<script src="https://unpkg.com/svg4everybody@2.1.9/dist/svg4everybody.min.js"></script>

In the next line, the function should be called:

<script>
svg4everybody();
</script>

Restart Storybook and see the result. Well.. it’s not working!

Solution

This is because the plain function call does not enable the polyfill for external sources. Extend the code with the polyfill option and restart Storybook. Now, the SVGs should be loaded correctly.

<script>
svg4everybody({ polyfill: true });
</script>

And you’re done!

Frontend / Angular Developer from Mainz, Germany. https://babettelandmesser.de

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store