A lightweight library that makes it easier to use SVG icons in your Angular Application
The svg-icon
library enables using the <svg-icon>
tag to directly display SVG icons in the DOM.
This approach offers an advantage over using an <img>
tag or via the CSS background-image
property, because it allows styling and animating the SVG with CSS.
For example, if the fill
or stroke
properties of elements in the svg are set to currentColor
, they will have the color defined for the containing DOM element. So the color can easily be changed by changing the color style on the svg-icon
element.
npm i @ngneat/svg-icon
npm i @ngneat/svg-generator --save-dev
src/assets/svg
tsconfig
file (optional):{
"paths": {
"@app/svg/*": ["src/app/svg/*"]
}
}
@ngneat/svg-generator
to clean and extract the icons content. Add the following to your package.json
file:{
"scripts": {
"prestart": "npm run svg",
"prebuild": "npm run svg",
"svg": "svg-generator"
},
"svgGenerator": {
"outputPath": "./src/app/svg",
"srcPath": "./src/assets/svg",
"svgoConfig": {
"plugins": [
"removeDimensions",
"cleanupAttrs",
{
"name": "convertColors",
"params": {
"currentColor": true
}
}
]
}
}
}
It can be modified to meet your needs.
outputPath
to your gitignore
filenpm run svg
Use the provideSvgIcons
to register the icons:
import { provideSvgIcons } from '@ngneat/svg-icon';
import { settingsIcon } from '@app/svg/settings';
bootstrapApplication(AppComponent, {
providers: [provideSvgIcons([settingsIcon])],
});
Now we can import the standalone SvgIconComponent
and use the svg-icon
component:
import { SvgIconComponent } from '@ngneat/svg-icon';
@Component({
imports: [SvgIconComponent],
template: `
<svg-icon key="settings"></svg-icon>
<svg-icon key="settings" color="hotpink" fontSize="40px"></svg-icon>
`,
})
export class FooComponent {}
Note that the key
should be striclty typed based on your icons. You can also export the SvgIcons
type from the library if you need it.
In lazy load modules or lazy routes, we can use the provideSvgIcons
method, for register icons accessible locally in these modules:
import { dashboardIcon } from '@app/svg/dashboard';
import { userIcon } from '@app/svg/user';
import { provideSvgIcons } from '@ngneat/svg-icon';
@NgModule({
declarations: [DashboardComponent],
providers: [provideSvgIcons([userIcon])],
imports: [DashboardRoutingModule],
})
export class DashboardModule {}
// OR in a Route def
{
path: 'dashboard',
providers: [provideSvgIcons([userIcon])],
component: DashboardPageComponent
}
Note that we're NOT using a barrel file (i.e index.ts
). This will make sure we only load the SVG files we use in the current module.
To make the process more seamless, the library provides a Webpack plugin you can use to automate the extracting process:
const { SvgGeneratorWebpackPlugin } = require('@ngneat/svg-generator/webpack-plugin');
{
plugins: [
new SvgGeneratorWebpackPlugin({
watch: !isProd,
srcPath: './src/assets/svg',
outputPath: './src/app/svg',
svgoConfig: {
plugins: ['removeDimensions'],
},
}),
];
}
There are cases where we want to group multiple SVG icons. For example, we might have a notifications
feature, and we need to load SVG icons such as Slack, Email, etc.
In such cases, create a unique directory, and put the related icons inside it. For example:
home.svg
user.svg
/notifications
- slack.svg
- email.svg
This will create a notifications
folder with a barrel
file that export the SVG icons inside the folder under a const named ${folderName}Icons
:
import { notificationsIcons } from '@app/svg/notifications';
@NgModule({
providers: [provideSvgIcons(notificationsIcons)],
})
export class NotificationsModule {}
To control the SVG size, we use the font-size
property as described in this article.
You also have the option to pass fixed sizes and use them across the application:
import { provideSvgIconsConfig } from '@ngneat/svg-icon';
bootstrapApplication(AppComponent, {
providers: [
provideSvgIconsConfig({
sizes: {
xs: '10px',
sm: '12px',
md: '16px',
lg: '20px',
xl: '25px',
xxl: '30px',
},
defaultSize: 'md',
icons,
}),
],
});
They are used in the size
input:
<svg-icon key="settings" size="lg"></svg-icon>
@Input() key: string;
@Input() size: string;
@Input() fontSize: string;
@Input() color: string;
@Input() width: string | number;
@Input() height: string | number;
@Input() noShrink: boolean;
You can inject the SvgIconRegistry
, and get existing SVG icons or register new ones:
import { SvgIconRegistry } from '@ngneat/svg-icon';
interface Icon {
name: string;
data: string;
}
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'],
})
export class AppComponent {
constructor(private registry: SvgIconRegistry) {
registry.register([Icon, Icon, Icon]);
registry.register(Icon);
registry.get(name);
registry.getAll();
}
}
You can also use the injectRegisterIcons
method to register icons using the new inject
API:
import { injectRegisterIcons } from '@ngneat/svg-icon';
interface Icon {
name: string;
data: string;
}
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'],
})
export class AppComponent {
constructor() {
injectRegisterIcons([Icon, Icon, Icon]);
}
}
You can define missingIconFallback which will be used if icon is not found in registry:
import { provideSvgIconsConfig } from '@ngneat/svg-icon';
import { unknownIcon } from '@app/svg/unknown';
bootstrapApplication(AppComponent, {
providers: [
provideSvgIconsConfig({
missingIconFallback: unknownIcon,
}),
],
});
The svgGenerator
config object is placed by default in your main package.json
.
It can also be placed in any location supported by the Cosmiconfig library such as a custom .svgGeneratorrc.json
file.
The config object is looked for in the project root directory by default.
If your config object is located in another directory, you can specify it through the --config-dir
option of the svg
CLI: npm run svg --config-dir=/your/custom/dir/where/the/config/is/located
. The config object will then be looked for in all valid Cosmiconfig library locations starting from that directory and going up the directory tree until a config is found.