Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/spiriitlabs/vite-plugin-svg-spritemap

Vite plugin to generate svg spritemap
https://github.com/spiriitlabs/vite-plugin-svg-spritemap

css spritemap svg vitejs vuejs

Last synced: 7 days ago
JSON representation

Vite plugin to generate svg spritemap

Awesome Lists containing this project

README

        

[![npm](https://img.shields.io/npm/v/@spiriit/vite-plugin-svg-spritemap)](https://www.npmjs.com/package/@spiriit/vite-plugin-svg-spritemap) [![node-current](https://img.shields.io/node/v/@spiriit/vite-plugin-svg-spritemap)](https://nodejs.org/) [![Coverage Status](https://coveralls.io/repos/github/SpiriitLabs/vite-plugin-svg-spritemap/badge.svg?branch=main)](https://coveralls.io/github/SpiriitLabs/vite-plugin-svg-spritemap?branch=main)

# vite-plugin-svg-spritemap

> This plugin supports Vite 4 and 5.

This ViteJS plugin generates a single SVG [spritemap](https://css-tricks.com/svg-sprites-use-better-icon-fonts/) with ``/``/`` for each SVG files. It can also generate a stylesheet (CSS/SCSS/Stylus/Less) containing the sprites to be used directly (via a Data URI or SVG fragments).

The plugin outputs can be fully configurable through [options](#🛠-options).

> [!NOTE]
> This plugin is inspired by [svg-spritemap-webpack-plugin](https://github.com/cascornelissen/svg-spritemap-webpack-plugin) for Webpack.

## 🚀 Features

- ⚡ Fully integrated in your ViteJS environment
- 📦 Pack your SVG files in one ([spritemap](https://css-tricks.com/svg-sprites-use-better-icon-fonts/)) file
- ✨ Use your SVG in an `` or `` tags and also directly in your CSS/SCSS/Stylus/Less
- 🍕 Import SVG fragment as VueJS component
- 🔥 HMR support

## 📦 Install

```shell
npm i -D @spiriit/vite-plugin-svg-spritemap

# yarn
yarn add -D @spiriit/vite-plugin-svg-spritemap

# pnpm
pnpm add -D @spiriit/vite-plugin-svg-spritemap
```

## 👨‍💻 Usage

By default, the plugin will generate a spritemap to support all methods described below (files populated with `` for fragments and `` for sprite).

```ts
// vite.config.js / vite.config.ts
import VitePluginSvgSpritemap from '@spiriit/vite-plugin-svg-spritemap'

export default {
plugins: [VitePluginSvgSpritemap('./src/icons/*.svg')]
}
```

You can access to the spritemap via the route `/__spritemap`. All files process by ViteJS will transform the path of the file on build. By default, you will need to use the prefix `sprite-`.

**SVG**

```html

```

**Img**

You need to add the suffix `-view` to access to the fragment.

```html

```

**CSS**

You can also use the spritemap SVGs in your CSS. The plugin supports CSS (basic classes) and also SCSS, Stylus and Less (mixins and map with SVG Data URI and sizes).

First you need to adjust the plugin options to set the output styles. For full styles options, check the [Options](#🛠-options).

```ts
// vite.config.js / vite.config.ts
import VitePluginSvgSpritemap from '@spiriit/vite-plugin-svg-spritemap'

export default {
plugins: [
VitePluginSvgSpritemap('./src/icons/*.svg', {
styles: 'src/scss/spritemap.scss'
})
]
}
```

```scss
// main.scss
@import './spritemap.scss';
```

After that, you need to import the file in your current styles. Don't forget to [load the CSS](https://vitejs.dev/guide/features.html#css) via ViteJS.

If you use a CSS preprocessing language, you can use the mixin `sprite` and access to a map with all sprites infos. If not, you will only access to classes.

You can see the usage in the demo folder :

- [CSS](/demo/basic/src/css/)
- [SCSS](/demo/basic/src/scss)
- [Less](/demo/basic/src/less/)
- [Stylus](/demo/basic/src/stylus/)

## Advanced

### Customize styles outputs

By default, the plugin will generate CSS or a mixin (for SCSS, Less and Stylus) with variables which contains all sprites data.

You can alter the output by using the `styles.callback`. You can access the default content generated by the plugin but you can also write your own output by using the createSpritemap function.

In the example below, this will generate only background data uri.

```ts
// vite.config.js / vite.config.ts
import VitePluginSVGSpritemap from '@spiriit/vite-plugin-svg-spritemap'

export default {
plugins: [
VitePluginSVGSpritemap('./src/icons/*.svg', {
styles: {
filename: 'src/scss/spritemap.css',
callback: ({ content, options, createSpritemap }) => {
let insert = ''
insert += createSpritemap((name, svg) => {
const selector = `.${options.prefix}${name}`
let sprite = ''
sprite = `${selector} {`
sprite += `\n\tbackground: url("${svg.svgDataUri}") center no-repeat;`
sprite += '\n}'
return sprite
})
return insert
}
}
})
]
}
```

You can use the `include` property to controle exactly what to include inside your style. If you want only variables with `['variables']` for SCSS/Less/Stylus or `['bg']` in CSS, only background css class generation for example.

You can also control the names of the `mixin`, the variables `sprites` and `prefix`.

```ts
// vite.config.js / vite.config.ts
import VitePluginSVGSpritemap from '@spiriit/vite-plugin-svg-spritemap'

export default {
plugins: [
VitePluginSVGSpritemap('./src/icons/*.svg', {
styles: {
filename: 'src/scss/spritemap.scss',
names: {
mixin: 'icon-sprite',
prefix: 'icon-prefix',
sprites: 'icons'
}
}
})
]
}
```

### Vue components

`vite-plugin-svg-spritemap` allows you to load icons and create `` as `` and `` as `` tags like Vue components.

To do that, import the icons loaded by `vite-svg-spritemap` and add the `?use` or `?view` query. The plugin will transform the component.

```vue

import SpiriitUse from './icons/spiriit.svg?use'
import SpiriitView from './icons/spiriit.svg?view'
import ViteUse from './icons/vite.svg?use'
import ViteView from './icons/vite.svg?view'



My superb logo


```

will generate

```html

My superb logo



```

You can see the usage in the [corresponding demo folder](/demo/vue/src/App.vue).

#### Typescript

For typescript, you need to load the type definitions inside `vite-env.d.ts` to fix errors with `?use`/`?view` query.

```ts
///
///
```

### Nuxt 3

> [!NOTE]
> This plugin only works with Nuxt 3 and Vite as a bundler.

You just need to install the plugin and set it in the right place for Nuxt 3.

```ts
// nuxt.config.ts
import VitePluginSvgSpritemap from '@spiriit/vite-plugin-svg-spritemap'

export default defineNuxtConfig({
vite: {
plugins: [
VitePluginSvgSpritemap('./assets/icons/*.svg'),
]
}
})
```

You can see the usage in the [corresponding demo folder](/demo/nuxt/app.vue).

#### Typescript

For usage with TypeScript, you will need to add in a `.d.ts` file the reference type `/// ` (see [issue #38](https://github.com/SpiriitLabs/vite-plugin-svg-spritemap/issues/38)) to use `?use`/`?view` query.

```ts
///
```

### Backend integration

ViteJS allows to be use to [serve assets](https://vitejs.dev/guide/backend-integration.html). So, you can connect ViteJS with Wordpress, Drupal or any kind of backend.

> [!IMPORTANT]
> To make `vite-plugin-svg-spritemap` works with this kind of environnment, you will need to handle the right url inside your backend if you are on dev or build.

For example, with `` on dev, using direcly the id of the svg (with the `injectSVGOnDev` option).

```html

```

And in prod, by putting the correct URL manually thanks to [the manifest.json file](https://vitejs.dev/guide/backend-integration.html) information :
```html

```

To prevent [CORS issue with SVG](https://oreillymedia.github.io/Using_SVG/extras/ch10-cors.html) and ``, you can use the `injectSVGOnDev` option. Don't forget to add the HMR script directly above you close body.

```html

```

You can see an example of integration in the [corresponding demo folder](/demo/server/routes/index.pug).

### Multiple Instance

If you want to have multiple SVG sprites files, you can configure multiple instances of the plugin. To do so, you will need the options `route`. Instead of the traditionnal `/__spritemap`, you can set for example `/__flags`.

```ts
// vite.config.js / vite.config.ts
import VitePluginSVGSpritemap from '@spiriit/vite-plugin-svg-spritemap'

export default {
plugins: [
VitePluginSVGSpritemap('./src/icons/*.svg'), // will be route: '__spritemap' by default
VitePluginSVGSpritemap('./src/flags/*.svg', {
route: '__flags'
})
]
}
```

If you are using Sass, Less or Stylus: you can optimize the style file export by only generate one mixin on one instance with `styles.include` set to `['variables']` or/and use the `styles.names` object.

## 🛠 Options

The first argument is a glob path (using [fast-glob](https://github.com/mrmlnc/fast-glob)) and the second is an object with the following options :

| Options | Type | Default | Description |
| -------------- | ----------------------------------- | --------- | ------------- |
| output | `boolean` or `object` or `string` | `true` | As a string, set the destination of the file (see [output.filename](#output)).
For more control, see [output](#output).
Set to false to disable output. |
| styles | `false` or `object` or `string` | `false` | File destination like `src/css/spritemap.css` or [styles object](#styles) |
| prefix | `string` or `false` | `sprite-` | Define the prefix uses for sprite id in ``/``/``.
Set to false to disable the prefix |
| svgo | `boolean` or `object` | `true` | Take an SVGO Options object.
If `true`, it will use the [default SVGO preset](https://github.com/svg/svgo#default-preset), if `false`, it will disable SVGO optimization |
| injectSVGOnDev | `boolean` | `false` | Inject the SVG Spritemap inside the body on dev |
| idify | `(name:string, svg:object) => string` | `name => options.prefix + name` | Function allowing to customize the id of each symbol of the spritemap svg. |
| route | `string` | `__spritemap` | Change the route name allowing you to have multiple instance of the plugin |

### output

| Options | Type | Default | Description |
| -------- | --------- | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| filename | `string` | `[name].[hash][extname]` | The destination of the file. You can use [output filename like Rollup](https://www.rollupjs.org/guide/en/#outputassetfilenames).
*Note: Doesn't support hash number.* |
| name | `string` | `spritemap.svg` | The name of file, appear on the manifest key |
| use | `boolean` | true | Insert `use` element in the spritemap |
| view | `boolean` | true | Insert `view` element in the spritemap |

### styles

| Options | Type | Description |
| -------- | ----------------------------------------- | -------------------------------------------------------------- |
| filename | string | The destination of the stylesheet file like your source folder |
| lang | `less`/`scss`/`styl`/`css` or `undefined` |Enforce the styles language generated by the plugin |
| include | boolean or `['mixin', 'variables']` or `['bg', 'mask', 'bg-frag']` or `undefined` | By default, it will include `['mixin', 'variables']` for SCSS/Less/Stylus and `['bg', 'mask', 'bg-frag']` for CSS. This allowing you to choose what to include |
| names | `{prefix: 'sprites-prefix', sprites: 'sprites', mixin: 'sprite'}` | Allow to customize the variables/mixin names of the generated Sass/Less/Stylus |
| callback | `undefined` | Allow you to customize the output of the generated styles file (see [Customize Styles Outputs](#customize-styles-outputs)) |

**Example with full options :**

```ts
// vite.config.js / vite.config.ts
import VitePluginSVGSpritemap from '@spiriit/vite-plugin-svg-spritemap'

export default {
plugins: [
VitePluginSVGSpritemap('./src/icons/*.svg', {
prefix: 'icon-',
route: '__spritemap',
output: {
filename: '[name].[hash][extname]',
name: 'spritemap.svg',
view: false,
use: true,
},
svgo: {
plugins: [
{
name: 'removeStyleElement',
},
],
},
injectSVGOnDev: true,
idefy: (name, svg) => `icon-${name}-cheese`,
styles: {
lang: 'scss',
filename: 'src/scss/spritemap.scss',
include: ['mixin', 'variables'],
names: {
prefix: 'sprites-prefix',
sprites: 'sprites',
mixin: 'sprite',
},
callback: ({ content, options, createSpritemap }) => {
return content
}
}
})
]
}
```

## 🏃 What's next

- Add variable supports inspired by [svg-spritemap-webpack-plugin](https://github.com/cascornelissen/svg-spritemap-webpack-plugin/blob/master/docs/variables.md)

## 👨‍💼 Licence

MIT