As a developer, you are probably familiar with the importance of creating high-quality and visually appealing graphics for your web applications. One of the best ways to achieve this is by using SVG. SVG is a powerful and versatile format that allows you to create and display vector graphics on the web. Since SVG is using XML to describe the graphics, generating dynamic SVGs can be quite useful and simple to implement.
Apparently, in Angular, we can use .svg
templates for components instead of the .html
files we are accustomed to. This opens the door to using Angular's syntactic sugar, like property binding and event binding, with SVGs to create dynamic and interactive graphic content.
In this blog post, we will take a closer look at how and why to use SVG templates in Angular. Using SVG templates in Angular allows you to create dynamic, responsive graphics that can change based on dynamic data or user interactions. This makes it a great choice for creating complex graphics, visualizations, and animations for your web applications.
To use SVG as an Angular template, first, you need an Angular project. Let’s create one:
ng new svg-demo
Now delete everything from app.component.html
and create a new component:
ng g c svg-demo
I usually manually change the .html
suffix to .svg
, delete its contents, and update the .ts
file with the new templateUrl
in the @Component
decorator.
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-svg-demo',
templateUrl: './svg-demo.component.svg',
styleUrls: ['./svg-demo.component.scss'],
})
export class SvgDemoComponent implements OnInit {
constructor() {}
ngOnInit(): void {}
}
CLI takes care of many things, such as adding component declarations to the @NgModule
decorator, and we can freely use it in the app.component.html
with the <app-svg-demo></app-svg-demo>
tag.
In svg-demo.component.svg
I’ll paste the SVG code for this isometric cube which I got from draw.io

Here is the contents of cube.svg
:
<svg width="91px" height="101px" viewBox="-0.5 -0.5 91 101" style="background-color: rgb(255, 255, 255);">
<g>
<path d="M 45 0 L 90 21.61 L 90 78.39 L 45 100 L 0 78.39 L 0 21.61 Z" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)"/>
<path d="M 0 21.61 L 45 43.21 L 90 21.61 M 45 43.21 L 45 100" fill="none" stroke="rgb(0, 0, 0)"/>
</g>
</svg>
To break this code down, the surrounding <svg>
tag contains one <g>
tag, which stands for "group" and groups two <path>
tags. Those two paths represent these two parts of our shape:

Now, let's make this markup more Angular-y and decide what we want to do with it.
One of the most basic things we can do in Angular Components is to bind .html
and .ts
files. In our case, we can bind values from .ts
to the values in .svg
. Let's consider the colors of those shapes and make the outline of the same color.
Below, we have just an array of colors
, a strokeColor
property, and a function that returns a randomly chosen color from the array.
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-svg-demo',
templateUrl: './svg-demo.component.svg',
styleUrls: ['./svg-demo.component.scss'],
})
export class SvgDemoComponent implements OnInit {
colors: string[] = [
'red',
'orange',
'yellow',
'green',
'blue',
'purple',
'black',
];
strokeColor: string | undefined;
constructor() {}
getRandomColor() {
const randomNumber = Math.floor(Math.random() * this.colors.length);
return this.colors[randomNumber];
}
ngOnInit(): void {
this.strokeColor = this.getRandomColor();
}
}
I want to bind the randomly chosen color to the stroke attribute of those two shapes, as we want to change both of them.
<svg width="91px" height="101px" viewBox="-0.5 -0.5 91 101" style="background-color: rgb(255, 255, 255);">
<g>
<path d="M 45 0 L 90 21.61 L 90 78.39 L 45 100 L 0 78.39 L 0 21.61 Z" fill="rgb(255, 255, 255)" [attr.stroke]="strokeColor" />
<path d="M 0 21.61 L 45 43.21 L 90 21.61 M 45 43.21 L 45 100" fill="none" [attr.stroke]="strokeColor" />
</g>
</svg>
Now the color of the stroke changes on every refresh. Let's also change the fill color of the first <path>
tag. I will modify the .ts
file for my purposes:
strokeColor: string | undefined;
// add new property
fillColor: string | undefined;
ngOnInit(): void {
this.strokeColor = this.getRandomColor();
// assign random color to this as well
this.fillColor = this.getRandomColor();
}
And I'll update the SVG template as well:
<svg width="91px" height="101px" viewBox="-0.5 -0.5 91 101" style="background-color: rgb(255, 255, 255);">
<g>
<path d="M 45 0 L 90 21.61 L 90 78.39 L 45 100 L 0 78.39 L 0 21.61 Z" [attr.fill]="fillColor" [attr.stroke]="strokeColor" />
<path d="M 0 21.61 L 45 43.21 L 90 21.61 M 45 43.21 L 45 100" [attr.fill]="fillColor" [attr.stroke]="strokeColor" />
</g>
</svg>
Here are the results of multiple reloads, all with different (random) colors:

Let's change the behavior and make the colors change on mouse click, instead of relying on the refresh button. We can use Angular's event binding syntax for this. I will modify the files once again:
changeColors() {
this.strokeColor = this.getRandomColor();
this.fillColor = this.getRandomColor();
}
ngOnInit(): void {
this.changeColors();
}
<svg width="91px" height="101px" viewBox="-0.5 -0.5 91 101" style="background-color: rgb(255, 255, 255);">
<g (click)="changeColors()">
<path d="M 45 0 L 90 21.61 L 90 78.39 L 45 100 L 0 78.39 L 0 21.61 Z" [attr.fill]="fillColor" [attr.stroke]="strokeColor" />
<path d="M 0 21.61 L 45 43.21 L 90 21.61 M 45 43.21 L 45 100" [attr.fill]="fillColor" [attr.stroke]="strokeColor" />
</g>
</svg>
That's basically it. If you want to move the shape, you can use the x
and y
attributes for each element, or for all of them at once with the parent tag.
Few things to keep in mind:
1. When Angular renders the SVG Component in the app-root, it is usually rendered inside a <div>-like element. And if you want to nest multiple SVG components, you should change the component selector and use the directive's syntax like this:
@Component({
selector: '[app-svg-demo]',
...
});
<svg app-svg-demo></svg>
2. We need to use [attr.X]
syntax to not get the following error:
error NG8002: Can't bind to 'fill' since it isn't a known property of ':svg:path'.
According to Angular documentation:
This error arises when attempting to bind to a property that does not exist. Any property binding must correspond to either:
- A native property on the HTML element, or
- An
@Input()
property of a component or directive applied to the element.
So by using [attr.X]
syntax, we make sure that Angular knows that we’re trying to bind the value to the native property on the HTML (in our case SVG) element.
3. We can as easily use the @Input
and @Output
data / event binding between a parent and child components.
4. We can also use structural directives *ngIf
/ *ngFor
with the SVG elements (don’t forget to add CommonModule
to the AppModule
imports).
5. SVG paths and shapes follow their order. The next element will be drawn on top of the previous one.