Scalable Vector Graphics (SVG) is a web standard that allows you to define two-dimensional vector graphics using an XML-based markup language. Using SVG images, especially for web development, has a ton of benefits. Luckily, Lightning Web Components (LWC) provide full built-in support for using them. In this post, we’ll cover different options when using SVGs in LWC.

Pixel vs. vector-based graphics

Pixel-based images (also known as raster or bitmap images) are created by defining a color for each individual pixel of the image. This gives an exact representation of a picture for its given size. But they’re difficult to scale or change. Some examples of pixel-based image formats are JPEG, GIF, PNG, TIF, BMP or PSD.

Vector-based graphics, in contrast, are made up by defining lines, curves, basic shapes, and text. These kind of images don’t lose quality when you scale them, can be easily created and modified, and they don’t require too much space on disk. Some vector-based image formats include AI, CDR or SVG.

Scalable Vector Graphics (SVG)

Scalable Vector Graphics (SVG) defines how to create scalable vector-based graphics using XML code. SVGs are well suited for web development, as XML plays nicely with HTML, JavaScript and CSS. SVGs support interactivity and animation, and can be easily modified in JavaScript thanks to the SVG DOM API.

Here is the Salesforce logo in SVG format:

If you’re not familiar with XML, you may be wondering what the meaning of the xmlns attribute is on the svg tag. This is the way we tell the user agent which namespace, or XML specification, the svg element and all its child element names (path in this case) belong to. Concretely, the SVG namespace is called http://www.w3.org/2000/svg

Styling SVGs with CSS is a common thing. For example, we could change the CSS fill attribute of our Salesforce logo background on hover state to reflect a different color:

Let’s explain what that CSS selector does. First, :hover selects the svg element when you mouse over it. In that case, we’ll select the first path child element found thanks to :first-of-type.

If you take a look at the Salesforce logo XML, you’ll see a fill attribute on each of the paths defined. This is a presentation attribute. Presentation attributes are equivalent to CSS properties applied through stylesheets or inline. However, CSS properties always override presentation attributes. This is exactly what is happening here. The CSS property provided in the stylesheets (fill:yellow) is overriding the path fill attribute on hover.

Ways to use SVGs in Lightning Web Components

Let’s explore the different ways in which you can use an SVG in Lightning Web Components. To exemplify the different alternatives, we’ll create a component that is an invitation to our fictitious annual Salesforce Awards event. The component will include the Salesforce logo SVG.


You will be able to check the complete code examples in this github repo afterwards.

Use the SVG inside an HTML template

This approach is as simple as it sounds. You can directly copy the SVG XML code into the HTML template of your component, and it will render as the image that you expect. Something like:

salesforceAwardsInvitation1.html

Although this option will have great performance — as no extra-network request is needed — it has poor reusability.

Create a dedicated component for loading your SVGs

An interesting option is to create a dedicated component to serve different SVGs. Each SVG can be stored in an independent template, and the component can be configured to serve the correct template depending on an @api property.

For this, we’ve created a component called logo and included two templates in it. One includes the SVG code for the Salesforce logo, and another one for the Google logo:

templates/salesforceLogo.html

templates/googleLogo.html

Now, we’ve implemented the logic to serve one template or the other based on an @api property called name. We’ll use the Salesforce logo as the default template.

logo.js

Finally, we can reference the logo component into our invitation, and configure it to return one of the templates:

salesforceAwardsInvitation2.html

This option needs to do an extra server trip to retrieve the component, but the component will serve all our SVGs, so it’s a good compromise between performance and reusability.

Store the SVG in a static resource

SVGs can be uploaded as static resources. Salesforce acts as a content distribution network (CDN) for static resources, handling automatic caching and distribution. Additionally, if you’re using SVGs to create an icon system, you can improve performance even more by combining the different icons into a single SVG sprite. This removes the need to do multiple round-trips to retrieve different icons.

Let’s take a look at two options to include an SVG static resource in your component.

Include the static resource SVG with use
If you need to configure the CSS of the SVG, as we did above, pick this solution. To follow this approach, you must add an id to the svg tag in your SVG file. This step is important, as without the id, the SVG won’t be loaded correctly:

salesforceLogo.svg

Next, you’ll have to import the static resource in your component, in the same way as with other static resources. Note that you’ll have to concatenate the resource URL with the id that you set in the svg tag, as follows:

salesforceAwardsInvitation3.js

Having done that, you can reference the SVG passing the static resource computed URL (svgURL) to the href attribute of the use element. The use element clones the referenced node and its children into the place where it’s used, in this case the component markup. The href element needs to include the node id, this is the reason why we added an id to the static resource.

salesforceAwardsInvitation3.html

If we take a look at the nodes that are generated by the use element, we’ll see that the SVG nodes have been copied as part of the invitation component DOM, but they are enclosed in a shadow DOM:

Note: you need to activate “Show user agent shadow DOM” in Chrome Developer Tools settings to be able to see Shadow DOM contents.

Shadow DOM elements cannot be accessed using regular CSS selectors. If we try to style the image in the same way that we did at the beginning of the blog post, it won’t work. However, we can set the fill attribute as inherit in the SVG path and control it from the parent.

salesforceLogo.svg

salesforceAwardsInvitation3.css

Note that we are not using the path element in CSS anymore. We cannot use it, because of Shadow DOM. But luckily, there is something we can leverage to overcome this. By definition, the styles you apply to use will be inherited by all its descendants. This works the same for other SVG tags that allow grouping, as g, defs or symbol. Therefore, we can style the use element, and the inner path elements will inherit that value.

Reference the static resource SVG with the image tag
This approach won’t copy the SVG nodes, but instead include them as an image. It’s a simpler approach, but it won’t allow you to modify the SVG CSS as we did above. In this case, you can upload it in a static resource as is. You don’t need to specify an id:

salesforceLogo.svg

Next, you’ll have to import the static resource in your component, same as in the previous case, but this time no id reference will be needed.

salesforceAwardsInvitation4.js

Finally, you’ll be able to reference the SVG passing the static resource computed URL (svgURL) to the src attribute of the image element.

salesforceAwardsInvitation4.html

Take a look at the nodes that are generated by using the image element. We can’t see the included SVG nodes anymore:

Use an SVG as a custom icon in Lightning App Builder or Community Builder

Another possible usage of SVGs in a Lightning Web Component is to use it to define an icon that will be visible in Lightning App Builder and Community Builder. This is done in the same way in Aura components and Lightning Web Components. For that, simply include an .svg file in the component folder and include the SVG code. The name of the .svg file must match the component name. Bear in mind, the component metadata file must be correctly configured so that the component is available for the different builders.

svgIconForBuilders.svg

When you take a look at the component in the builders, it will look like the following:

Restrictions and compatibility

There are some things that you should keep in mind when working with SVGs in LWC:

  • Modern versions of Edge, Google Chrome, Safari and Firefox already support SVG. However, this is not true for older versions of browsers, or Internet Explorer 11. To overcome this, there is a nice JavaScript library that you can use, called svg4everybody. This library solves that problem by adding SVG support to almost all browsers. You can include the library in a static resource and use it in your component as explained here.
  • Not all the existing SVG tags are supported by LWC. You can check the list of supported tags here.

Conclusion

As you’ve seen, SVG is a great image format to be used in web development, as SVGs can be scaled without loss of quality, and can be easily modified and animated with code. Lightning Web Components provides built-in support for them, and we’ve seen the different ways in which you can use an SVG in LWC. Remember to check this github repo to see the code for all examples shown.

Related Links

Get the latest Salesforce Developer blog posts and podcast episodes via Slack or RSS.

Add to Slack Subscribe to RSS