A Vite plugin that builds icon sprites from multiple SVG or PNG icon files.
This plugin collects multiple SVG or PNG image files, assembles them into a single icon sprite file, and provides virtual modules that can be imported in source code.
In Vite server mode, the icon sprite files will be generated on demand. When bundling the project, all icon sprite files referenced in source code will be generated and bundled.
It is possible to instantiate this plugin repeatedly, e.g. in order to generate an SVG sprite and a PNG sprite in the same project.
Common configuration options for SVG sprites and PNG sprites.
- Type:
"svg" | "png"
- required
The file format specifier of the icon sprite, and the source images. Depending on the value of this option, the plugin expects various file-format specific options (see below).
- Type:
string
- required
Path to root directory with all image resource files to be processed.
- Type:
string
- required
Path to the JSON or YAML configuration file containing the mapping between icon identifiers and SVG source file names (see below).
The plugin collects multiple SVG files, and generates a virtual import for an SVG sprite file with multiple <symbol>
elements that can be imported from source code.
Example how to consume the SVG sprite in source code:
// path/to/source.ts
import svgSprite from "virtual:svg/my-icons.svg"
// insert the SVG sprite into the DOM to be able to refer to the <symbol> elements
document.createElement("div").innerHTML = svgSprite
// create an SVG element referring to an icon in the sprite
function createIcon(id: string): SVGElement {
const useEl = document.createElementNS("http://www.w3.org/2000/svg", "use")
useEl.setAttribute("href", "#my-icon")
const iconEl = document.createElementNS("http://www.w3.org/2000/svg", "svg")
iconEl.append(useEl)
return iconEl
}
- Type:
string
- required
The module name of the SVG sprite to be generated (with ".svg" extension).
The SVG markup of the sprite can be imported from the virtual module path "virtual:svg/[spriteName]"
.
- Type:
string
- optional
A prefix to be added to all icon identifiers declared in the mapping file. By default, no prefix will be added.
// vite.config.ts
import { defineConfig } from "vite" // or "vitest/config"
import spritePlugin from "@open-xchange/vite-plugin-icon-sprite"
export default defineConfig(() => {
plugins: [
spritePlugin({
format: "svg",
imagesPath: "src/icons/images",
mappingPath: "src/icons/svg-mapping.yaml",
spriteName: "icons.svg",
idPrefix: "svg-",
}),
],
})
- Collects all SVG files in the directory
src/icons/images
. - Uses the icon mapping in
src/icons/svg-mapping.yaml
. - Creates a virtual import
"virtual:svg/icons.svg"
. - Prefixes all icon identifiers with
svg-
, e.g. the icon keymy-icon
in the mapping file will result in the icon identifier"svg-my-icon"
in source code.
The plugin collects multiple PNG files, and generates a virtual imports for one or more sprite files with different icon sizes and a CSS file that can be imported from source code.
- Type:
string
- required
The module name for the CSS file (with ".css" extension). The generated CSS markup can be imported from "virtual:png/[cssName]"
.
- Type:
number
- required
Base size of all icons, in CSS pixels.
- Type:
number
- Default:
0
Additional padding around all icons to be generated in the sprites, in CSS pixels.
- Type:
string
- Default:
"i.png-icon"
The CSS selector for a PNG icon element to be used in all generated CSS rules.
- Type:
string
- Default:
"lang"
Name of the root element's attribute containing the locale identifier. Needed to generate CSS selectors for localized icons.
- Type:
"source" | "monochrome" | "alpha"
- Default:
"source"
Specifies how to generate the sprite PNG files.
Value | Description |
---|---|
"source" |
The source PNGs will be copied into the generated sprites unmodified. They will contain three color channels, and an alpha channel. |
"monochrome" |
The generated sprites will be converted to monochrome. They will contain a gray channel and an alpha channel. |
"alpha" |
Only the alpha channels of the source PNGs will be copied into the generated sprites. They will contain a single gray channel representing the original alpha channels. |
- Type:
"background" | "mask"
- Default:
"background"
Specifies how the sprites are supposed to be used in CSS rules.
| Value | Description |
| "background"
| The sprites will be attached via "background-image". |
| "mask"
| The sprites will be attached via "mask-image". |
All related CSS properties (e.g. background-position
vs. mask-position
etc.) will be generated accordingly.
- Type:
Record<string, { factor: number; src: string }>
- required
List of all icon sprites with different icon sizes to be generated.
-
The keys of the dictionary are the module names of the PNG sprites (with ".png" extension). The generated PNG sprite can be imported from
"virtual:png/[key]"
. -
The values of the dictionary contain configuration options for the PNG sprite:
Option Type Default Description factor
number
required Icon scaling factor (a multiplier for plugin option cssIconSize
). All source PNG files must have the effective pixel size (cssIconSize * factor
).src
string
required The pattern used to build the path of the source PNG files. MUST contain the placeholder [path]
that will be replaced with the base paths contained in the icon mapping file.
// vite.config.ts
import { defineConfig } from "vite" // or "vitest/config"
import spritePlugin from "@open-xchange/vite-plugin-icon-sprite"
export default defineConfig(() => {
plugins: [
spritePlugin({
format: "png",
imagesPath: "src/icons/images",
mappingPath: "src/icons/png-mapping.yaml",
cssName: "icons.css",
cssIconSize: 16,
cssIconPadding: 1,
cssIconSelector: "i.my-icon",
rootLocaleAttr: "data-icon-locale",
spriteColorType: "alpha",
spriteFillType: "mask",
sprites: {
"icons1.png": { factor: 1, src: "[path]_16.png" },
"icons2.png": { factor: 2, src: "[path]_32.png" },
},
}),
]
})
- Collects all PNG files in the directory
src/icons/images
. The images must exist in two sizes (16px and 32px), their file names must end with_16.png
and_32.png
respectively (according to the optionscssIconSize
andsprites->factor
). - Uses the icon mapping in
src/icons/png-mapping.yaml
. - Creates the virtual imports
"virtual:svg/icons.css"
,"virtual:svg/icons1.png"
, and"virtual:svg/icons2.png"
. - Adds one pixel padding around all icons in the PNG sprites.
- Generates CSS selectors for
<i>
elements with CSS classmy-icon
. - Generates
:root[data-icon-locale]
CSS selectors for localized icons (i.e., the UI locale code must be stored in the root element's attribute "data-icon-locale"). - Generates PNG sprites consisting of an 8-bit alpha channel only.
- Generates CSS rules using CSS mask (instead of background).
The plugin expects an icon mapping file (plugin option mappingPath
) which is a JSON or YAML configuration file containing a mapping from arbitrary icon identifiers to the paths of the source images. The icon identifiers can be used later in source code to refer to a specific icon in the generated sprite.
-
The name of the configuration file can be chosen freely.
-
The configuration file must consist of a single object map.
-
Each entry maps a unique icon identifier (used in source code) to a source image to be used for that icon.
-
The source image file can be specified directly as string, or as dictionary for localized icons (more details below).
-
Only the base name of the source image file must be specified relative to the configured root directory of the image files. It must not contain the image size suffix (PNG only), nor a file extension (
.svg
or.png
). See examples below. -
Localized icons will be described by a dictionary mapping the ISO language identifiers (as comma-separated strings) to the image base names (as described above). The special locale code
"*"
is mandatory, and defines a default icon for unlisted locales. See examples below.
In all examples, the configured image root directory (plugin option imagesPath
) shall be path/to/images
.
- Assign the icon with the identifier
my-icon
to the SVG imagepath/to/images/commons/icon1.svg
. - Assign the icon with the identifier
other-icon
to the SVG imagepath/to/images/commons/icon2.svg
.
# svg-mapping.yaml
my-icon: commons/icon1
other-icon: commons/icon2
In source code, the icons can be used with the identifiers "my-icon"
and "other-icon"
.
Assuming that the plugin will generate PNG sprites for icons with sizes of 16px and 32px.
- Assign the icon with the identifier
my-icon
to the PNG imagespath/to/images/commons/icon1_16.png
(16x16 pixels) andpath/to/images/commons/icon1_32.png
(32x32 pixels). - Respectively, assign an icon with the identifier
other-icon
to the PNG imagespath/to/images/commons/icon2_*.png
.
The resulting mapping file looks exactly as the former mapping file for SVG icons:
# png-mapping.yaml
my-icon: commons/icon1
other-icon: commons/icon2
- Assign the icon with the identifier
my-icon
to the SVG imagepath/to/images/commons/icon1.svg
by default. - Use the SVG image
path/to/images/commons/icon2.svg
in German and French UI instead. - Use the SVG image
path/to/images/commons/icon3.svg
in Swedish UI instead.
# svg-mapping.yaml
my-icon:
"*": commons/icon1
de,fr: commons/icon2
sv: commons/icon3
The same applies to PNG icons as well.
This package provides a JSON schema that can be used for validation in editors.
Add the path to the schema file as property "$schema"
to the mapping file:
// mapping.json
{
"$schema": "../../node_modules/@open-xchange/vite-plugin-icon-sprite/dist/mapping-schema.json",
// ...
}
Adjust the number of parent path fragments according to the location of the mapping file in the project.
Add the path to the schema file in a yaml-language-server
directive to the mapping file:
# mapping.yaml
# yaml-language-server: $schema=../../node_modules/@open-xchange/vite-plugin-icon-sprite/dist/mapping-schema.json
# ...
Adjust the number of parent path fragments according to the location of the mapping file in the project.
In VS Code, the plugin redhat.vscode-yaml needs to be installed to support this directive.
By default, warning messages and error messages will be logged to the shell. The environment variable PLUGIN_REPLACE_ICON_SPRITE
can be used to change the log level of this plugin. Possible values are info
, warn
, error
, and silent
.