The project aims to generate an SVG sprite that enables us to achieve the following objectives:
- Optimize the use of SVG files through the creation of an SVG icon component;
- Allow the editing of SVG files without losing their functionality when using the
<img/>
tag. - Automatically regenerate the SVG sprite when icons are added, edited, or removed, and the app is running.
- Reduce the number of HTTP requests when fetching icons from the assets folder by using a service for loading SVG icons.
Run the commands in your project:
npm install svg-sprite --save-dev
npm install onchange --save-dev
npm install npm-run-all --save-dev
npm install uuid
- Script file: generate-svg-sprite.js.
Where:
ICONS_PATH
is the path where your svg-icons are located;SVG_SPRITE_PATH
is the path where your generated sprite will be located;SVG_SPRITE_FILENAME
is the name of the sprite that you want to save.
- Sprite loader service: sprite-loader.service.ts;
- Svg service: svg.service.ts.
- Svg icon component: svg-icon.component.ts.
-
start
allows us to wait for svg-sprite generation and app startup, and begin monitoring svg file changes to regenerate the sprite as needed:"start": "npm-run-all --parallel serve watch-sprite"
-
serve
allows us to generate the svg-sprite and run our app:"serve": "npm run generate-sprite && ng serve"
-
build
allows us to prepare the svg-sprite before making the app build & build the app:"build": "npm run generate-sprite && ng build"
-
generate-sprite
allows us to generate the svg-sprite file by running the script:"generate-sprite": "node scripts/generate-svg-sprite.js"
-
watch-sprite
allows us to listen the svg-icon changes during the running of app (adding/editing/removing icons, etc.) & regenerate the sprite build:"watch-sprite": "onchange \"./src/assets/icons/**/*.svg\" --initial --kill -- npm run generate-sprite"
# Auto-generated sprites folder
svg-sprite.svg
Adding icons to template:
<svg-icon [src]="<your-icon-name-here>"></svg-icon>
Changing icon styles (optional):
-
Way #1: Changing colors by ::ng-deep.
svg-icon::ng-deep { svg path { fill: <some-color-here>; } }
or
svg-icon::ng-deep { svg path { stroke: <some-color-here>; } }
-
Way #2: Changing colors by font color of the parent element.
<svg xmlns="http://www.w3.org/2000/svg" ...> <!-- fill --> <path fill="currentColor" ... /> <!-- or stroke --> <rect stroke="currentColor" ... /> </svg>
and setting the font color in CSS / SCSS / SASS / Less.
svg-icon { color: <some-color-here>; }
The usage of fill
or stroke
depends on the <path>
type in the svg file.
During sprite generation, we ensure that all linear and radial gradient IDs in SVGs are unique to prevent conflicts when multiple icons use gradients. This prevents issues with color references when multiple SVGs are displayed, ensuring that each SVG maintains its intended gradient coloring even if others are added or removed from the DOM.
We have enhanced the way SVGs are processed during sprite generation:
- Automatic ID Uniqueness: All elements with
id
attributes in SVGs are automatically assigned unique IDs to avoid conflicts. This includes not only gradients (linear and radial) but any other elements that use anid
. The uniqueness is ensured by appending a unique suffix to each originalid
. - Reference Updates: All references to these IDs are automatically updated across the SVG. This includes any usage within attributes such as
fill
,stroke
,filter
,clip-path
,mask
,marker-start
,marker-mid
,marker-end
,style
, and even directhref
orxlink:href
attributes.