Using inline SVG within a Vue.js component

Recently, I embarked on a Vuejs project using @vue/cli version 3.0.0-beta.16. In my Home.vue single file component, I encountered an issue while trying to import and add inline SVG to the template.

The crux of the problem lies in the fact that vue cli already associates the .svg file extension with the file-loader configuration:

webpackConfig.module
  .rule('svg')
    .test(/\.(svg)(\?.*)?$/)
    .use('file-loader')
      .loader('file-loader')
      .options({
        name: getAssetPath(options, `img/[name].[hash:8].[ext]`)
      })

After experimenting with the html-loader plugin to incorporate SVG within the template, I discovered it only worked after removing the default svg configuration in my vue.config.js and implementing my custom loader like such:

// vue.config.js

chainWebpack: config => {
    const svgRule = config.module.rule('svg')

    svgRule.uses.clear()

    svgRule
    .test(/\.(svg)$/)
    .use('html-loader')
    .loader('html-loader')
    .options({
    })
}

As for the template implementation:

// Home.vue

<div v-html="require('./../assets/inline.svg')"></div>

However, a new problem emerged where the html-loader also replaced the SVG src within <img /> tags with inline SVG code. My goal is to utilize file-loader for

<img src="something.svg" />
and html-loader for require('./inline.svg'). Can multiple loaders be applied to the same rule in webpack? Is my current approach correct? Any insights would be greatly appreciated.

Edit Upon reflection, I suspect I may have incorrectly added both loaders. This is how I inserted them into 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']
})

Answer №1

If you want to modify the existing loaders set up by the webpack config, simply add a leading ! in the require expression.

<div v-html="require('!html-loader!./../assets/inline.svg')"></div>

This approach does not require any changes to the vue.config.js file, assuming html-loader is already installed.


Alternatively, consider using svg-inline-loader instead of html-loader. This loader can automatically add hashes to classes and ids, preventing any potential name collisions when dealing with multiple inline svgs on a single page.

Answer №2

If you do not currently have the html-loader package installed, you can easily add it by running the following command:

yarn add -D html-loader

Next, insert the following configuration object into the rules array in your webpack configuration file:

{
  test: /\.svg$/,
  use: [{ loader: 'html-loader' }]
}

After completing these steps, you will be able to import svg files into your scripts using the inline loader.

require('!html-loader!./../assets/inline.svg')

// or you can include it directly in your v-html directive
<div v-html="require('!html-loader!./../assets/inline.svg')"></div>

Answer №3

Just a little further, specify to Webpack the loader to utilize:

<div v-html="require('html-loader!./../assets/inline.svg')"/>

Answer №4

To utilize both webpack loaders, consider specifying in your html loader to target only div elements with v-html. This can be achieved by adding the following syntax in the loader options:

{
  attrs: ['div:v-html']
}

Explore the documentation for the html loader at this link.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Configuring Access-Control-Allow-Origin does not function properly in AJAX/Node.js interactions

I'm constantly encountering the same issue repeatedly: XMLHttpRequest cannot load http://localhost:3000/form. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8000' is therefor ...

The Vue and Typescript webpage is not appearing in the GAS sidemenu template

I am tasked with developing an application for Google Sides using Vue + Typescript to enhance its functionality with an extra menu feature. You can find a sample without Typescript here. The result is visible in this screenshot: https://gyazo.com/ed417ddd1 ...

Tips for populating a DOJO Select using JSON data that includes various parameters instead of just label and value

I am trying to populate a DOJO select element with JSON data where the item values for value are expressed by the code property. Here's an example of what I have: //require dojo Select var select = new Select({ name: "stateSelect", ...

Is this example a strong demonstration of implementing simple inheritance in JavaScript?

Having transitioned from using Dojo, there's one specific thing that I deeply miss - Dojo's declare() function. Developing a rather complex application, I found myself extensively modifying Node's lang.inherits() to enhance its functionality ...

Updating tag content dynamically using jQuery

I have the following HTML code: <div class="selfclear"> <h3><a id="lnkName" href="/dir/subdir/?id=577">Name</a></h3> <address> Street name, 3 <br />3222 City<br />Phone. ...

encountering a problem while trying to run `npm install react-native-modal-datetime-picker` in the terminal

I've encountered an issue while working on my app where I keep getting errors when trying to install the react-native-modal-datetime-picker package, as well as other date time picker packages like @react-native-community/datetime-picker The specific ...

Transferring information from JavaScript to PHP

I am trying to send both the data and text that are within a single DIV tag using JavaScript into PHP values. However, I am encountering an issue with the following code: <html> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jq ...

Template displaying multiple polymer variables side by side

Here is the date object I am working with: date = { day: '05' } When I use this code: <div>{{date.day}}</div> It generates the following HTML output: <div>05</div> Everything looks good so far. Now, I want to try th ...

Using Enzyme.configure inside a Jasmine helper function

I am currently utilizing Enzyme with React 16 using Karma, Jasmine, and webpack. In one of my tests, I set up the Enzyme adapter within the beforeEach function as shown below: import React from 'react'; import Enzyme, { shallow } from 'enzy ...

Leverage the power of JavaScript by utilizing it as the view

Currently, in my React app, the view engine is set to hbs. There are a few hbs files in the Views folder. The following code snippet is in my app js file: // View engine app.engine( 'hbs', hbs({ extname: 'hbs', }) ) app.set ...

Develop universal style classifications for JSS within material-ui

Currently, I am utilizing the JSS implementation of material-ui to style my classes. As I have separated my components, I find myself dealing with a significant amount of duplicated code in relation to the components' styles. For instance, I have mu ...

A unique approach to handling ngdisabled for fields that are required only

Starting off with a requirement to disable the submit button when a required field is left empty. <form name="form"> <input type="text" placeholder="First Name" data-ng-model="model.firstName" name="FirstName" ng-required="true" /><br/> ...

Steps for iterating through an array within an object

I currently have a JavaScript object with an array included: { id: 1, title: "Looping through arrays", tags: ["array", "forEach", "map"] } When trying to loop through the object, I am using the following ...

Issues are arising with Bootstrap's functionality within the Vite React app

I am new to working with react and vite. I am currently developing a vite react application that requires the use of bootstrap. I followed the instructions provided on the official Bootstrap website here. However, not all Bootstrap functionalities are work ...

Issues with Django Site Search Functionality

Currently working on a Django project, I have encountered an issue with the search bar on my localhost site. Despite adding the search bar, it fails to return any results when provided input. Upon inspecting the page source, I discovered some unfamiliar li ...

Could the issue be related to a bug in the combination of ng-repeat and ngInclude?

I've been experimenting with loading different templates in this manner: <div ng-class="{active:$first,in:$first,'tab-pane':true}" id="{{p.path}}_settings" ng-repeat="p in panes" ng-include="buildPath(p.path)"> </div> Here&apos ...

What is the method to disable response validation for image endpoints in Swagger API?

I'm working with a Swagger YAML function that looks like this: /acitem/image: x-swagger-router-controller: image_send get: description: Returns 'image' to the caller operationId: imageSend parameters: ...

Exploring the concept of JavaScript Variablesqueries

I need help understanding why the results are different in these three examples related to JavaScript. Case 1. var x = 5 + 2 + 3; document.getElementById("demo").innerHTML = x; Result: 10 Case 2. var x = 5 + 2 + "3"; document.getElementById("demo").in ...

Calculate the total sum of selected values in a multiple select dropdown using jQuery

Is there a way to calculate the sum of selected items in a multiple selection dropdown menu? For instance, if I select "X12SO" and "X13SO", their values should add up to 30. let total = 0; $("select[name='myselect[]'] option").each(function(){ ...

What is the best way to bring an image into your nextjs project?

I have a question about importing images into my Next.js project. I created an array of objects and want to import an image stored in a folder on my laptop, specifically in the src folder rather than the public folder. How can I properly achieve this in ...