Ali Soueidan

Ali Soueidan Front-End Developer

👋 Hello, I am Ali, a Developer based in Hamburg/Germany, and this is my Blog.

Dealing with SVGs in Vue

SVGs are awesome, they have small size, can be scaled infinitely and they can be manipulated using JavaScript or CSS to simply change their color or even animate them. In Vue we have several possibilities dealing with SVG files – within this article I’d like to discuss some solutions, what are their advantages or disadvantages and how to implement them.

Using the image tag

Using the image tag (img) isn’t the best (in my opinion) yet the simplest way of using SVGs within a Vue application! One just sets the SVG file as the image within the source property of the image tag, as one would do it with any other image – simple as that!

Pros

  • Very easy implementation.
  • No additional stuff to handle alongside the SVGs them self, therefor an easy to handle solution.
  • Clean Markup

Cons

  • SVG manipulation using CSS and JS is limited (like every other image format as like png or jpg).

It might look like the pros are overweighting – in my opinion that is only the case, if you really just want to use the SVG as like an image, without being able to change its color or so – then this could be a go to solution – I myself like to keep the option open to use SVGs in their full bandwidth when possible.

Using a template engine

Some projects use template engines to define their markup, which has many advantages beyond simply implementing SVGs in an application, of course. Anyways, an easy implementation of SVGs can be an advantage of using template-engines as well. For example using Pug.js, where one simply can import SVGs and use them as like the SVG code would be within the Markup.

Importing an SVG in Vue, using Pug.js as a template engine

Within the code example above you can see how to import an SVG file, directly into the markup, using Pug. Pug provides „includes“ which allow to insert code from one file into another, and also works with SVGs as well. To describe it a little better, Pug uses a nested syntax (as like Python e.g.), in the code example I am defining a link (using an AnkerTag-Component, which has several properties), then I nest the include into the AnkerTag-Component (which has a default slot), by simply writing include and the relative path towards the SVG file at the end I also push some text into the slot as well (by writing `| LinkedIn`).

Pros

  • Clean Markup
  • Maintaining full potential of SVGs, by being able to change them or even animating the using CSS and/or JavaScript.
  • Benefit from extended functionality of the Template Engine (not related to SVG only)
  • Easy to use (if one already knows pug)

Cons

  • One hast to learn a template engine like pug (if don’t know one yet)
  • One has to get used to a changed markup syntax – some might find the nested syntax confusing (which I often hear but cannot really comprehend)
  • One has to use an additional dependency
  • Using a template engine does gain complexity respectively the level of knowledge a developer needs to have or gain to handle the code basis, and therefore new team members might be harder to find or need more time to work properly within the project.

Now the SVG is behaving as like you’ve pasted the entire SVG code into your markup, but using pug our markup stays much cleaner (SVG files can contain lots of code) – this is in my opinion a very handy solution, I really love to work with – not only because of how easy one can import SVGs, but because I love the Pug syntax and as I said before Pug provides more functionality – if you’re interested – the documentation describes the whole package.

Using SVG components

This a simple yet a good way of using SVGs within your vue application. Comes with some more advantages and can even be combined with the template engine approach. Using this approach we would build one component for each SVG we want to use in our application – simple as that.

An advantage of this method (whether we use a template engine or not) is, that one can import SVGs as like components, and therefor can include these into our Markup in a clean way – the related SVG code would be written within our component itself, not polluting our current markup at all – as you can see in the following Codesandbox example down below

Also all the related code could be bundled within our single file component, which includes the SVG code, maybe some additional JavaScript to handle user interactions with our component a.k.a. SVG, and even the related CSS e.g. for animations using css keyframes would be in place with the other related code (can be seen within the Codesandbox example above as well `src/components/VueIcons.vue`) – that sounds very cool to me!

Pros

  • Still unpolluted, clean markup since SVG component is outsourced to component.
  • All the SVG related code is bundled together in one single file.
  • Keeping the full potential of SVGs, being able to manipulate them, and can even extend the functionalty within the component making the interactive by default e.g.
  • Can even be combined with the template engine approach (resulting in additional pros and cons, related to that one)

Cons

  • One hast to write a component for each single SVG, which will be used within an application.

In some cases it can make sense to leave the basic styling of the component to the parent component (as like in the Codesandbox example), so the related CSS is structured together, at the place where it is needed, in other cases it could make absolutely sense including it within the SVG component itself and adding e.g. some extra properties to change it. To decide whats better in your case of course is up to you.

Conclusion

I myself like using template engines like pug since I like the clean syntax and the extended functionality beyond easy including SVGs to my markup – anyways, if including SVGs is your only problem to solve, using a template engine would be a little exaggerated. Using the SVG components approach could be a better fit in that case – since you can stick to HTML, and still have clean Markup, since the bloated SVG code stay in its component – using this approach you can even extend the SVGs functionality by making it interactive or animated by default – for example some of the SVGs on my main-page alisoueidan.com are based on that approach. You could e.g. click on one of the SVG images, which will trigger an animation. Using the image tag, you will still benefit of the small file size of SVG, on the other hand you will loose all the other benefits, why I use this approach only, when I know that I wont use the SVG only in a simple displaying context.