Vue SVG Loader
`vue-svg-loader` is a Webpack loader designed to transform SVG files directly into functional Vue components, allowing developers to easily embed, style, and dynamically manipulate SVG assets within their Vue applications. The current stable version is 0.16.0, which primarily supports Vue 2 projects. However, version 0.17.0 is actively being developed in beta, with a strong focus on introducing robust Vue 3 compatibility. While its release cadence has historically been somewhat sporadic, recent activity indicates renewed development efforts, particularly for Vue 3. Key differentiators include its seamless integration into the Vue build process, automatic SVGO optimization (with an option to disable it), and the generation of functional components utilizing ESM exports since version 0.11.0, which contributes to better performance and tree-shaking capabilities.
Common errors
-
Module parse failed: Unexpected token (1:0) You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file.
cause Webpack is encountering an SVG file but does not have a rule configured to process it with `vue-svg-loader` or another appropriate loader.fixAdd or correct the `vue-svg-loader` rule in your `webpack.config.js` to specifically target `.svg` files, ensuring it's applied before any generic asset loaders that might just copy the file. -
Cannot find module 'vue-template-compiler' or its corresponding type declarations.
cause The required peer dependency `vue-template-compiler` is missing from your project's `node_modules` in a Vue 2 application.fixInstall the `vue-template-compiler` package: `npm install vue-template-compiler --save-dev`. Ensure its version is compatible with your Vue 2 installation. -
TypeError: Cannot read properties of undefined (reading 'someSvgoOption') OR Invalid SVGO config
cause The `svgo` options provided to `vue-svg-loader` in your Webpack configuration are incorrect, malformed, or deprecated due to updates in the underlying `svgo` library.fixReview the `svgo` documentation for the version bundled with `vue-svg-loader` and update your `svgo` options within `webpack.config.js`. You can also try setting `svgo: false` in the loader options to temporarily disable SVGO. -
[Vue warn]: Failed to resolve component: MyIcon
cause The imported SVG component is not correctly registered within your Vue component's `components` option, or there's a mismatch in the component's name/casing between the `import` and its usage in the template.fixEnsure the imported SVG (e.g., `import MyIcon from './my-icon.svg';`) is explicitly listed in the `components` option of your Vue component (e.g., `components: { MyIcon }`) and used with the correct casing in the template (e.g., `<MyIcon />`).
Warnings
- breaking Since v0.11.0, generated SVG components now utilize ESM export format. This might require adjustments in older CommonJS-centric build environments or specific tooling configurations to ensure proper module resolution and effective tree-shaking.
- breaking The `toString()` method was removed from the SVG component definition in v0.6.0. This means you can no longer retrieve the absolute path of an imported SVG file by calling `MyIcon.toString()` on the imported component.
- breaking SVGO configuration options have changed across different versions of `svgo` (e.g., v1.0.4 in v0.5.0, v1.1.1 in v0.10.0). Providing outdated or incorrect `svgo` options in `vue-svg-loader` config can lead to errors or unexpected SVG output.
- gotcha The current stable release (v0.16.0) is primarily designed for Vue 2 applications and requires `vue-template-compiler@^2.0.0` as a peer dependency. Vue 3 support is being developed in the `0.17.0-beta` branch and is not yet considered stable for production use.
- gotcha `vue-svg-loader` has a peer dependency on `vue-template-compiler` for Vue 2 projects, typically requiring a version compatible with your installed `vue` package (e.g., `^2.0.0`). Failure to install this dependency or installing an incompatible version will result in build errors.
Install
-
npm install vue-svg-loader -
yarn add vue-svg-loader -
pnpm add vue-svg-loader
Imports
- SVG Component Import
const MyIcon = require('./assets/my-icon.svg');import MyIcon from './assets/my-icon.svg';
- Webpack Loader Configuration
{ test: /\.svg$/, loader: 'vue-svg-loader' }{ test: /\.svg$/, use: ['vue-loader', 'vue-svg-loader'] } - Loader Options Configuration
{ loader: 'vue-svg-loader', svgo: { plugins: [{ removeViewBox: false }] } }{ loader: 'vue-svg-loader', options: { svgo: { plugins: [{ removeViewBox: false }] } } }
Quickstart
import Vue from 'vue';
import App from './App.vue';
import TestIcon from './assets/test.svg';
// webpack.config.js (excerpt)
// module.exports = {
// module: {
// rules: [
// { test: /\.vue$/, loader: 'vue-loader' },
// { test: /\.js$/, loader: 'babel-loader' },
// { test: /\.svg$/, use: ['vue-loader', 'vue-svg-loader'] },
// ],
// },
// resolve: {
// extensions: ['.js', '.vue', '.json', '.svg']
// }
// };
// App.vue
<template>
<div id="app">
<h1>Welcome to Vue SVG Loader Example</h1>
<p>Here's a dynamically styled SVG icon:</p>
<TestIcon class="my-icon" :width="100" :height="100" />
<p>Another icon, with default sizing:</p>
<OtherIcon />
</div>
</template>
<script>
import OtherIcon from './assets/other.svg';
export default {
name: 'App',
components: {
TestIcon, // Register the imported SVG as a component
OtherIcon
}
}
</script>
<style>
.my-icon {
fill: blueviolet;
stroke: darkblue;
stroke-width: 2px;
transition: all 0.3s ease;
}
.my-icon:hover {
fill: hotpink;
transform: scale(1.1);
}
</style>
new Vue({
render: h => h(App),
}).$mount('#app');