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']
})
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']
})
Share
Improve this question
edited Jun 13, 2018 at 12:37
Atta ur Rehman
asked Jun 13, 2018 at 10:11
Atta ur RehmanAtta ur Rehman
911 gold badge1 silver badge7 bronze badges
1
- Hope, It`s help: stackoverflow.com/questions/49383528/… – Irony Commented Jul 28, 2018 at 12:23
4 Answers
Reset to default 6You 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>
You're almost there, just tell Webpack which loader to use:
<div v-html="require('html-loader!./../assets/inline.svg')"/>
You may want to use both webpack loaders, but also to tell your html loader to restrict to div
elements with v-html
with the following syntax in the loader options:
{
attrs: ['div:v-html']
}
Docs for the html loader are found there.