I have created a Vuejs project using @vue/cli version 3.0.0-beta.16 and in my Home.vue single file component I want to import and add inline SVG in the template but I am having trouble doing so.
The problem is vue cli is already using .svg file extension for file-loader like so:
webpackConfig.module
.rule('svg')
.test(/\.(svg)(\?.*)?$/)
.use('file-loader')
.loader('file-loader')
.options({
name: getAssetPath(options, `img/[name].[hash:8].[ext]`)
})
I have already tried using the html-loader plugin for including svg in the template and it works fine if I clear the svg default use in my vue.config.js and add my own loader like this:
// vue.config.js
chainWebpack: config => {
const svgRule = config.module.rule('svg')
// clear all existing loaders.
// if you don't do this, the loader below will be appended to
// existing loaders of the rule.
svgRule.uses.clear()
// add replacement loader(s)
svgRule
.test(/\.(svg)$/)
.use('html-loader')
.loader('html-loader')
.options({
})
}
and in my template:
// Home.vue
<div v-html="require('./../assets/inline.svg')"></div>
But the problem is it also replaces svg src in the <img />
tags with inline svg code. What I want is use file-loader for <img src="something.svg" />
and use html-loader for require('./inline.svg')
. How do I use multiple loaders for same rule in webpack? Or is it the right approach? Any help would be appreciated.
Edit I think the problem is I'm adding the both loaders the wrong way. This is how I add them in my file:
// vue.config.js
svgRule
.test(/\.(svg)$/)
.use('file-loader')
.loader('file-loader')
.options({
name: getAssetPath(options, `img/[name].[ext]`)
})
svgRule
.test(/\.(svg)$/)
.use('html-loader')
.loader('html-loader')
.options({
attrs: ['div:v-html']
})
You can add a leading !
in the require expression to "override" existing loaders set up by the webpack config.
<div v-html="require('!html-loader!./../assets/inline.svg')"></div>
This will work without changes to the vue.config.js
(as long as html-loader is installed)
Also, instead of using html-loader look into svg-inline-loader in can add hashes to classes and ids, so you don't need to worry about name collisions if you have multiple inline svgs on your page.
If you don't have html-loader
installed simply execute
yarn add -D html-loader
Then add the following object to the rules
array in your webpack config file:
{
test: /\.svg$/,
use: [{ loader: 'html-loader' }]
}
And finally, you will be able to import svg
files to your scripts with the inline loader.
require('!html-loader!./../assets/inline.svg')
// or directly in your v-html directive
<div v-html="require('!html-loader!./../assets/inline.svg')"></div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With