Magical SVG 🪄
An all-in-one Vite plugin that magically makes working with SVGs and bundling them a breeze.
Inspired by a tweet from Preact's creator Jason Miller, I've been looking at plugins that would let me work with SVGs, as I myself did the error of embedding SVGs as React components. Shame!
What I wanted was a plugin that would let me import SVGs, and make a sprite of symbols and give me the identifier I
can use in <use href='???'/>
. And I couldn't find any decent plugin that makes working with them easy. They all had
a problem that made using them a pain, or outright impractical. Here's a list of the problems I encountered:
- References in SVG files are never processed.
<image href='...'/>
would never get processed and the referenced asset is ignored. - The generated sprite include ALL icons, even unused ones. Just picking the right icons from a pack isn't an option.
- There are no options to output to a separate file and reference it. Inlining is apparently the only way.
- Selectively tell to not process a specific SVG isn't possible (e.g.: A logo, or SVGs that break when encapsulated in a symbol).
- You can't make different sprites, it's only all-in-one.
So I decided to make my own tool to solve all this problems. Introducing: the Magical SVG plugin. 🪄
Install
pnpm i vite-plugin-magical-svg
yarn add vite-plugin-magical-svg
npm i vite-plugin-magical-svg
Usage
Vite plugin setup
import { defineConfig } from 'vite'
import magicalSvg from 'vite-plugin-magical-svg'
export default defineConfig({
plugins: [
magicalSvg({
// By default, the output will be a dom element (the <svg> you can use inside the webpage).
// You can also change the output to react (or preact) to get a component you can use.
target: 'preact',
// By default, the svgs are optimized with svgo. You can disable this by setting this to false.
svgo: false
})
]
})
Targets
-
dom
(default): exports a function you can call (takes no arguments) and returns a DOM element. -
react
: exports a functional React component (wrapped inforwardRef
) -
preact
: exports a functional Preact component (wrapped inforwardRef
)
Use in code
import MySvg from './assets/icon.svg' // Basic import, as a sprite
import MySvg from './assets/icon.svg?sprite=owo' // Named sprites
import MySvg from './assets/icon.svg?sprite=inline' // Special sprite, inlined in the HTML document
import fileUrl from './assets/icon.svg' // Works like .png and other file imports
SVG processing
<svg viewBox='0 0 250 250'>
<image href='./assets/image.png'> <!-- Image will be imported, bundled, and the href will be replaced -->
<image href='./assets/icon.svg'> <!-- SVG will be imported as a file (implicit ?file) -->
<use href='./assets/icon.svg'> <!-- SVG will be imported and added to the sprite -->
</svg>
exports
note
This plugin does not respect the exports
field when importing svg files from third-party packages such as
simple-icons
, which do not expose them.