vue-svg-loader-2: SVG as Vue Components
The `vue-svg-loader-2` package is a webpack loader designed to enable the direct import and usage of SVG files as Vue components within web applications. It serves as a actively maintained fork of the original `vue-svg-loader`, ensuring continued compatibility with modern build environments and addressing dependency updates. The current stable version is 0.17.1. While there isn't a strict, predictable release cadence, the project demonstrates ongoing activity through consistent dependency updates and minor fixes, indicating active maintenance. Its primary utility lies in simplifying the integration of SVGs into Vue applications, allowing developers to leverage Vue's component system for features like props, slots, and reactivity. It integrates seamlessly with popular webpack-based setups such as Vue CLI and Nuxt.js, and includes internal SVG optimization capabilities via SVGO.
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 lacks the necessary configuration for `vue-svg-loader-2`, or the existing configuration for `.svg` files is incorrect or incomplete.fixVerify that your `webpack.config.js`, `vue.config.js` (for Vue CLI), or `nuxt.config.js` includes a rule to apply `vue-loader` and `vue-svg-loader-2` to `.svg` files. -
Error: SVG content could not be parsed: [specific XML parsing error details]
cause The SVG file being processed might be malformed or contain invalid XML. Alternatively, the internal SVGO optimization configuration might be too aggressive or incompatible with the SVG's structure.fixFirst, check the SVG file for any syntax errors or corruption. If the SVG is valid, review any custom SVGO options being passed to `vue-svg-loader-2` and try simplifying them or disabling problematic plugins. -
[Vue warn]: Unknown custom element: `<MyIcon>` - did you register the component correctly? For recursive components, make sure to provide a 'name' option.
cause The imported SVG file, which is treated as a Vue component by the loader, has not been correctly registered within the `components` option of the parent Vue component where it is being used, or the import path to the SVG is incorrect.fixEnsure that the imported SVG component (e.g., `import MyIcon from './assets/my-icon.svg'`) is explicitly added to the `components` object of the Vue component where it's being rendered, like `components: { MyIcon }`. Also, double-check the import path for accuracy.
Warnings
- breaking Major version updates of the underlying SVGO library (e.g., from v2 to v3 as seen in `0.17.0-beta.4`) can introduce breaking changes in SVG optimization behavior, potentially altering rendered output or requiring updates to SVGO configuration options.
- gotcha Webpack 5's built-in asset modules can conflict with `vue-svg-loader-2` when processing SVG files. This often results in SVGs being handled incorrectly or not at all.
- gotcha When integrating with Nuxt.js, the default internal webpack rule for handling SVG files must be modified to exclude `.svg` extensions before adding the `vue-svg-loader-2` rule. Failure to do so can lead to conflicts where two rules attempt to process the same file type.
- gotcha The order of loaders in the webpack `use` array is critical. `vue-loader` must be applied *before* `vue-svg-loader-2` to ensure that the SVG content is first processed into a format recognizable by Vue.
Install
-
npm install vue-svg-loader-2 -
yarn add vue-svg-loader-2 -
pnpm add vue-svg-loader-2
Imports
- SvgComponent
import { MyIcon } from './assets/my-icon.svg';import MyIcon from './assets/my-icon.svg';
- WebpackConfiguration
const config = require('./webpack.config'); // CommonJS import of webpack config is fine, but misconfiguring rules is a pitfallmodule.exports = { module: { rules: [ { test: /\.svg$/, use: ['vue-loader', 'vue-svg-loader-2'], }, ], }, }; - NuxtConfiguration
module.exports = { build: { extend: (config) => { const svgRule = config.module.rules.find(rule => rule.test.test('.svg')); svgRule.test = /\.(png|jpe?g|gif|webp)$/; config.module.rules.push({ test: /\.svg$/, use: ['vue-loader', 'vue-svg-loader-2'], }); }, }, };
Quickstart
<template>
<nav>
<a href="https://github.com/vuejs/vue">
<VueLogo />
Vue
</a>
<a href="https://github.com/svg/svgo">
<SVGOLogo />
SVGO
</a>
<a href="https://github.com/webpack/webpack">
<WebpackLogo />
webpack
</a>
</nav>
</template>
<script>
import VueLogo from './public/vue.svg';
import SVGOLogo from './public/svgo.svg';
import WebpackLogo from './public/webpack.svg';
export default {
name: 'Example',
components: {
VueLogo,
SVGOLogo,
WebpackLogo,
},
};
</script>