Vanilla JS awesome SVG loader demo
This project demonstrates vite-awesome-svg-loader capabilities, and how it works with different SVG images.
As an example, actual icons and line art images are present.
Import images via URL and render with regular <img> tag
Imports used in this section can be configured using regexes in plugin config (see vite.config.ts file).
Original files
Preserve line width
Try scaling images using slider at the bottom of the screen. Line width will stay the same despite image size.
Render images with SvgImage component
This component will render SVG source code into a SVG symbol, so you'll have more freedom to manipulate it. Most importantly, it allows you to set custom colors.
Original files
Preserve line width
Preserve line width and replace colors
Render icons with SvgIcon component
This component simplifies icons colorization and sizing.
It makes sense to always preserve icon's line width. In real project this should be done via config (see vite.config.ts file).
Original files
Preserve line width and replace colors
Animate color
The example above but we'll animate colors using CSS.
Automatically reuse same SVG in multiple symbols
This example demonstrates that one SVG is being reused in multiple SvgImage and SvgIcon components.
You can verify that images are reused by finding <symbol> element with the same ID as href attribute of the <use> elements. There should be only one <symbol> element with that ID.
SvgImage
SvgIcon
Plugin config demo
All images transformations are configured at vite.config.ts file. All files in each entry are actually different files in different directories: one directory for each section.
Each directory contains following files:
- skip-transforms.svg - configured to be skipped while transforming. This is the last file in each entry.
- skip-loading.svg - configured to not be loaded by vite-awesome-svg-loader. We'll show how it works in the last section.
Directory config-demo/all additionally contains following files:
- colors-not-preserved.svg - configured to be skipped while replacing colors.
- line-width-not-preserved.svg - configured to be skipped while preserving line width.
- ignore-elements.svg - file is transformed, but certain elements are ignored.
Preserve line width
Replace color
Every transform: preserve line width and replace color
All transforms except certain SVG elements
It's possible to skip transforms per-element and per-element-per-file. See vite.config.ts file for examples.
Skip loading entirely
These files are configured to be skipped by vite-awesome-svg-loader entirely. This is useful, for example, when you want to use other loader.
Since we're not using any other loader, we'll just get file path.
Here's the list of these files:
Named icons with dynamic imports inside icon component
This is just an example, you should implement your own component that handles loading state, errors, etc.
Other rendering methods
So far we've demonstrated two rendering methods: URL and source code that's being reused as a symbol. Let's see how else we can render images.
These methods are less performant than what we've already discussed. However, they may have their use-cases.
Put SVG directly into the DOM
This is what all UI frameworks do. However, this approach is recommended only when you need full control over SVGs. For other purposes, use other rendering methods such as URL or symbols.
Data URI
SVGs can be loaded as a Data URI and displayed by setting <img src="data:image/svg+xml;..."> or background-image: url("data:image/svg+xml;...") .
vite-awesome-svg-loader supports source code and base64 Data URIs. It also can load raw base64.
Source code data URI, original files
Base64 data URI, original files
Base64, original file
There's base64 data that's replaced with this text for assistive technologies.
Caveats
Stroke width should be in CSS pixels
When preserving line width, stroke width should be in CSS pixels. Image size doesn't matter. This is how it looks like:
Incorrect stroke width will result in something like this:
Preserving line width works only on strokes
Create your images with strokes instead of filled path to preserve line width.
Toggle original image to see that there's no difference when stroke is not preserved.
Transparent colors should be omitted or set as none or transparent
Quite common catch is to set white color and then wonder why image is messed up. If you don't want fill, omit it or set to none or transparent.
Recipes
Multicolored icons
Here we'll see how we can implement icons that have multiple colors, for example:
Our solution should be extensible, i.e. if accent color changes, we as developers should change only one line of code.
CSS variables
Classic solution is to use variables in SVG files and render then directly. We'll use CSS variables as well but leverage SVG symbols to improve rendering performance. This is done by using SvgImage or SvgIcon components.
setCurrentColorList option should not be used for multicolored icons because recoloring is done via CSS variables.
Here's the result where we can manipulate colors however we wish:
Since we're using variables instead of single color, for icons it's recommended to create a wrapper around SvgIcon and omit color prop.
Composite images
We can create separate SVG files and overlay them on top of each other.
This allows us not to modify SVG files which is good for complex images. However, creating a good abstraction over layers can be quite challenging.
Here's how composite image may look like:
Antipatterns
Colorize some elements and ignore others with skipSetCurrentColorSelectors or skipTransformsSelectors options. This will not be extensible, and it'll hurt build performance. Don't use these options to achieve any such functionality.