npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

unplugin-svg-transformer

v1.0.32

Published

Import easily your SVG with Vite.

Downloads

627

Readme

Banner with unplugin logo and unplugin-svg-transformer title, a SVG logo inserted for svg in title

unplugin-svg-transformer

unplugin version downloads license

tests codecov style

Import easily your SVG. Powered by unplugin.

Designed to be a replacement of kiwilan/nuxt-svg-transformer, a Nuxt module.

Use SVG into modern tools is not easy, especially when you want to use SVG as component. This plugin will parse your SVG files and create a cache file to import them easily with a library index file. It works with any framework with Vite/Webpack, but some components are ready-to-use for Vue, Nuxt and React. You could also create your own component for your favorite framework. Built for TypeScript, but works with JavaScript.

Note

If you want to use SVG from icon sets, you should use unplugin-icons, a very good plugin from unplugin. unplugin-svg-transformer is only for custom SVG.

import type { SvgName } from "unplugin-svg-transformer/icons";
import { importSvg, svgList } from "unplugin-svg-transformer/icons";

const icon: SvgName = "svg-name";
const svg = await importSvg("svg-name"); // param fully typed (SvgName), string output
const list = svgList; // as Record<SvgName, () => Promise<{ default: string }>>

Note

A demo is available on Stackblitz or directly on github.com/ewilan-riviere/unplugin-svg-transformer-example.

Features

Roadmap

  • [ ] Add Nuxt 2 support
  • [ ] Add more tests
  • [ ] Add SVGO support

Install

npm i unplugin-svg-transformer -D
# or
pnpm install unplugin-svg-transformer -D
# or
yarn add unplugin-svg-transformer -D
// vite.config.ts
import svgTransformer from "unplugin-svg-transformer/vite";

export default defineConfig({
  plugins: [
    svgTransformer({
      /* options */
    }),
  ],
});

Examples for Vue, React and Svelte:

// rollup.config.js
import svgTransformer from "unplugin-svg-transformer/rollup";

export default {
  plugins: [
    svgTransformer({
      /* options */
    }),
  ],
};

// webpack.config.js
module.exports = {
  /* ... */
  plugins: [
    require("unplugin-svg-transformer/webpack")({
      /* options */
    }),
  ],
};

// nuxt.config.ts
export default defineNuxtConfig({
  buildModules: [
    "unplugin-svg-transformer/nuxt", // https://github.com/kiwilan/unplugin-svg-transformer
  ],
  svgTransformer: {
    /* options */
  },
});

This module works for Nuxt 3 only

Example: live/nuxt3

// vue.config.js
module.exports = {
  configureWebpack: {
    plugins: [
      require("unplugin-svg-transformer/webpack")({
        /* options */
      }),
    ],
  },
};

// esbuild.config.js
import { build } from "esbuild";
import svgTransformer from "unplugin-svg-transformer/esbuild";

build({
  plugins: [
    svgTransformer({
      /* options */
    }),
  ],
});

Usage

unplugin-svg-transformer works with any framework with Vite/Webpack, but some components are ready-to-use for Vue and React. You could also create your own component for your favorite framework (only Javascript, TypeScript, Vue 3, React, Svelte and Nuxt 3 have been tested).

Options

Note

Nuxt 3 have some built-in options defined statically, because it uses amazing Nuxt 3 features. If ✅ option is available, otherwise is static.

| Name | Type | Description | Default | Nuxt | | :----------------------: | :---------------------: | :------------------------------------------------------------------------------------------: | :--------------------------------------------: | :---------------: | | cacheDir | string | SVG files will be added to cache directory. | ./node_modules/unplugin-svg-components/cache | ./.nuxt/icons | | fallback | string | Default SVG displayed when the SVG is not found. | <svg>...</svg> | ✅ | | global | boolean | Create icons.d.ts file at the root of your project. | false | | | libraryDir | string | Directory where icons.ts will be created. | ./src | ./.nuxt | | svgDir | string | Directory where your SVG files are located. | ./src/svg | ✅ ./assets/svg | | svg.classDefault | string[] | Add default classes to all SVG. | undefined | ✅ | | svg.clearSize | all, parent, none | Clear width and height attributes from SVG (can be all, just parent on <svg> or none). | none | ✅ | | svg.clearClass | all, parent, none | Clear classes from SVG (can be all, just parent on <svg> or none). | none | ✅ | | svg.clearStyle | all, parent, none | Clear inline styles from SVG (can be all, just parent on <svg> or none). | none | ✅ | | svg.currentColor | boolean | Add fill="currentColor" or stroke="currentColor" to all SVG. | false | ✅ | | svg.inlineStyleDefault | string[] | Add default inline style to all SVG. | undefined | ✅ | | svg.sizeInherit | boolean | Add inline style height: inherit; width: inherit;. | false | ✅ | | svg.title | boolean | Add title to SVG string. | false | ✅ | | useTypes | boolean | Use types, if you want to use JavaScript instead of TypeScript. | true | true | | warning | boolean | Trigger a warning when the SVG is not found. | false | ✅ |

Add your SVG files

In plugin options, you can add a directory to watch SVG files: svgDir. By default, it's ./src/svg (for Nuxt 3, it's ./assets/svg). Just put your SVG files into this directory and they will be parsed and added to library file, icons.ts.

Note

You can use SVG nested directories, but you can't have two SVG files with the same name.

An example of svgDir directory:

├── src
│   ├── svg
│   │   ├── download.svg
│   │   ├── social
│   │   │   └── twitter.svg
│   │   └── vite.svg
│   └── ...
└── ...

This example will give you this list: ['download', 'social/twitter', 'vite'].

Library file

In plugin options, you can add a directory to choose where to create library file: libraryDir. By default, it's ./src (for Nuxt 3, it's ./.nuxt). A library file will be created, icons.ts (or icons.js if useTypes is set to false), into this directory. This file will list all SVG files, used by importSvg function.

With TypeScript, SvgName type is available. And with JavaScript or TypeScript, you can use svgList and importSvg function. SVG list is updated when you add, remove or update a SVG file.

Note

A symlink of this file will be created into unplugin-svg-transformer/icons.

An example of icons.ts file:

export type SvgName = "download" | "social/twitter" | "vite" | "default";
export const options = {...};
export const svgList: Record<SvgName, () => Promise<{ default: string }>> = {
  download: () => import(".../cache/download"),
  "social/twitter": () => import(".../cache/social/twitter"),
  vite: () => import(".../cache/vite"),
  default: () => import(".../cache/default"),
};

export async function importSvg(name: SvgName): Promise<string> {
  // ...
}

if (typeof window !== "undefined") {
  window.ust.options = options;
  window.ust.svgList = svgList;
  window.ust.importSvg = importSvg;
}

Import SVG

You can easily import a SVG file with importSvg function from unplugin-svg-transformer/icons and use SvgName type (globally registered) to validate your SVG file name. svgList function list all SVG files, used by importSvg function.

import type { SvgName } from "unplugin-svg-transformer/icons";
import { importSvg, options, svgList } from "unplugin-svg-transformer/icons";

// `SvgName` type represents SVG file name
const icon: SvgName = "svg-name";
// importSvg function is async, you can use `await` or `then` method
const icon = await importSvg("svg-name");
// or
const icon = "";
importSvg("svg-name").then((svg) => {
  icon = svg;
});

const fallback = options.fallback; // All options are available

You can use Window to access svgList and importSvg functions from ust (not SSR compatible).

const svg = await window.ust.importSvg("svg-name");

Ready-to-use components

With some frameworks, you don't have to create your own component, you can use ready-to-use components.

Warning

Assure you have import unplugin-svg-transformer/icons into main.ts or app.ts (or app.js) when you use ready-to-use components: import 'unplugin-svg-transformer/icons' (except for Nuxt). Why? Because ready-to-use components use window to access to importSvg function (of course for Nuxt 3, you don't have to import unplugin-svg-transformer/icons because component use #icons alias).

// main.ts
import "unplugin-svg-transformer/icons";
  • For Vue 3, you can use a plugin to register globally SvgIcon component with SvgTransformerPlugin from unplugin-svg-transformer/vue and use SvgIcon component directly. But you can just import SvgIcon component from unplugin-svg-transformer/vue and use SvgIcon component.
  • For React, you can import SvgIcon component from unplugin-svg-transformer/react.
  • For Nuxt 3, you have a globally registered SvgIcon component, you can use SvgIcon component directly. You have an alias to use easily icons: #icons, same as unplugin-svg-transformer/icons.

All ready-to-use components have a name prop, based on SVG file name. You can use name prop to validate SVG file name.

| Prop name | Prop type | Required | Prop description | | :--------: | :-------: | :------: | :-----------------------------------------------------------------: | | name | SvgName | ✅ | SVG file name | | title | string | | Add title to SVG | | reactive | boolean | | Add watch to update SVG if name update (not available on React) |

Create your own component

  • For Svelte, no component available, you have to create your own, you can use example: ./examples/svelte/src/lib/SvgIcon.svelte.
  • For vanilla JS or TS, you can import importSvg function from unplugin-svg-transformer/icons to import SVG file.
  • For Vue or React, you can create your own component like with Svelte.

TypeScript or JavaScript

To use JavaScript only, set useTypes option to false, but this plugin is built for TypeScript first. You can use SvgName type to validate your SVG file name.

import type { SvgName } from "unplugin-svg-transformer/icons";

const icon: SvgName = "svg-name";

If you use only JavaScript you can import your SVG with same way without type validation.

Global type

If you use Vite (with Vue, React or Svelte) or Nuxt, SvgName is globally imported by default. But if you use another bundler or vanilla JS/TS and you want to globally import SvgName, you can add global option to true in plugin options to create icons.d.ts at root of project to add SvgName globally. You might have to add include: ["icons.d.ts"] into tsconfig.json.

Note

With Vue, React and Svelte, this plugin use vite-env.d.ts to add SvgName globally, global option is not needed (same for Nuxt).

// tsconfig.json, if you enabled `global` option.
{
  "include": ["icons.d.ts"]
}

And enable global option in plugin options.

// vite.config.ts (or webpack.config.js, rollup.config.js, ...)
import svgTransformer from "unplugin-svg-transformer/vite";

export default defineConfig({
  plugins: [
    svgTransformer({
      global: true,
    }),
  ],
});

Advanced examples

Vue 3

An example with Vue 3 and Vite.

You can skip SvgTransformerPlugin registration, this plugin will only load SvgIcon component globally, you can import SvgIcon component from unplugin-svg-transformer/vue and use SvgIcon component. But you have to import unplugin-svg-transformer/icons in main.ts if you want to use SvgIcon component.

// main.ts
import { createApp } from "vue";
import App from "./App.vue";
+import { SvgTransformerPlugin } from 'unplugin-svg-transformer/vue'
+import "unplugin-svg-transformer/icons";

createApp(App)
+ .use(SvgTransformerPlugin)
  .mount("#app");

Inertia

An example with Laravel Jetstream (Inertia) and Vite. This example will use TypeScript, but it works with JavaScript. For TypeScript, you will have to create tsconfig.json file at root of project, here a example.

Note

This example use Vue 3, but it works with React or Svelte.

To use TypeScript, update vite.config.js to vite.config.ts and just add unplugin-svg-transformer/vite to plugins array.

Warning

Don't forget to replace resources/js/app.js to resources/js/app.ts into laravel-vite-plugin options.

import { defineConfig } from "vite";
import laravel from "laravel-vite-plugin";
import vue from "@vitejs/plugin-vue";
+import svgTransformer from "unplugin-svg-transformer/vite";

export default defineConfig({
  resolve: {
    alias: {
      "@": "/resources/js",
      "~": "/",
    },
  },
  plugins: [
    laravel({
+     input: ["resources/js/app.ts"],
      ssr: "resources/js/ssr.js",
      refresh: true,
    }),
    vue({
      template: {
        transformAssetUrls: {
          base: null,
          includeAbsolute: false,
        },
      },
    }),
+   svgTransformer({
+     svgDir: "./resources/js/Svg",
+     libraryDir: "./resources/js",
+     global: true,
+   }),
  ],
});

Just replace app.js to app.ts into resources/js (and root Blade file).

// app.ts
import type { DefineComponent } from "vue";
import { createApp, h } from "vue";
import { createInertiaApp } from "@inertiajs/vue3";
import { resolvePageComponent } from "laravel-vite-plugin/inertia-helpers";
+import { SvgTransformerPlugin } from "unplugin-svg-transformer/vue";
+import 'unplugin-svg-transformer/icons'

createInertiaApp({
  title: (title) => `${title} - App Name`,
  resolve: (name) =>
    resolvePageComponent(
      `./Pages/${name}.vue`,
      import.meta.glob("./Pages/**/*.vue")
    ) as Promise<DefineComponent>,
  setup({ el, App, props, plugin }) {
    const app = createApp({ render: () => h(App, props) })
      .use(plugin)
+     .use(SvgTransformerPlugin);

    app.mount(el);
  },
});

And you can use globally registered SvgIcon component.

<template>
  <div>
    <SvgIcon name="svg-name" />
  </div>
</template>

React

An example with React and Vite.

You have to import unplugin-svg-transformer/icons only once in main.tsx (or app.tsx), you can use SvgIcon component if you import it from unplugin-svg-transformer/react.

// main.tsx
import React from 'react'
import ReactDOM from 'react-dom/client'
+import { SvgIcon } from 'unplugin-svg-transformer/react'
import './index.css'
+import 'unplugin-svg-transformer/icons'

const root = document.getElementById('root') as HTMLElement
ReactDOM.createRoot(root).render(
  <React.StrictMode>
    hello
+   <SvgIcon name="svg-name" className='icon' />
  </React.StrictMode>,
)

Nuxt 3

An example with Nuxt 3.

Installation on Nuxt 3 is easily with nuxt.config.ts file.

// nuxt.config.ts
import { defineNuxtConfig } from "nuxt3";

export default defineNuxtConfig({
  buildModules: [
    "unplugin-svg-transformer/nuxt", //
  ],
  svgTransformer: {
    /* options */
  },
});

And you can use globally registered SvgIcon component or #icons alias.

<script setup lang="ts">
import { importSvg } from "#icons"; // `#icons` alias

const svg = ref<string>("");
importSvg("svg-name").then((icon) => {
  svg.value = icon;
});
</script>

<template>
  <div>
    <div v-html="svg" />
    <SvgIcon name="svg-name" />
  </div>
</template>

Testing

pnpm test

Local

pnpm package

In package.json:

{
  "devDependencies": {
    "unplugin-svg-transformer": "file:~/unplugin-svg-transformer.tgz"
  }
}

Changelog

Please see CHANGELOG for more information on what has changed recently.

Credits

License

The MIT License (MIT). Please see License File for more information.