Loading SVGs on the fly with Vue3 and Vite

Currently, I am in the process of transitioning my Vue2/Webpack application to Vue3/Vite.

Here's an example of what works in Vue2/Webpack:

<div v-html="require('!!html-loader!../../assets/icons/' + this.icon + '.svg')"></div>

To include html-loader, I have added the following configuration:

"html-loader": "1.3.2",

However, when attempting the same approach in Vue3/Vite, I encounter the error:

ReferenceError: require is not defined

I've searched for a solution that allows dynamic file loading without knowing the filename during compilation. Is there a way to achieve this?

Answer №1

Another option is to implement the Lazy Load Components technique using the defineAsyncComponent feature in Vue3. You can find more information about this approach in this link.

Alternatively, you can also use import() as demonstrated by @tony19 in their answer on Stack Overflow:

<script>
const loadImage = async imgName => {
  const module = await import(/* @vite-ignore */ `../assets/images/${imgName}.jpg`)
  return module.default.replace(/^\/@fs/, '')
}

export default {
  data() {
    return {
      image: null,
      imageName: 'image1', // image1.jpg
    }
  },
  watch: {
    imageName: {
      async handler(imgName) {
        this.image = await loadImage(imgName)
      }, 
      immediate: true,
    },
  },
}
</script>

<template>
  <button @click="imageName = 'image2'">Load Another Image</button>
  <img :src="image" alt="Loaded Image" />
</template>

Answer №2

If you're interested in integrating SVG files into your Vue components, I suggest checking out the vite-svg-loader plugin for Vite.

Answer №3

One way to incorporate icons into your project is by creating a component that handles loading the icons, utilizing the composition API in Vue.

<template>
    <i v-html="svg" />
</template>

<script lang="ts" setup>
    import { computed } from 'vue';

    const props = defineProps(['icon', 'src']);
    const path = props.src ? props.src : '';
    const file = `${path}icon-${props.icon}`;
    const modules = import.meta.glob('../../assets/icons/**/*.svg', { as: 'raw' });

    const svg = computed(() => {
        return modules['../../assets/icons/' + file + '.svg'];
    });
</script>

<style lang="scss" scoped></style>

This approach also allows for custom styling of the SVG elements using CSS frameworks like TailwindCSS.

To use this component:

<UiIcon icon="NAME" class="w-8 fill-current text-red-500"/>

And you're good to go!

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

There was an issue encountered while trying to install Electron using the command 'npm install electron'

While attempting to install electron using npm install electron, I encountered the following error: 908 error code 1 909 error path C:\Users\name\Documents\name\Code\code\node_modules\gl 910 error command failed ... ...

Mastering Kendo UI in Vue: The Ultimate Guide to Managing Child Checkboxes in TreeView

I am currently utilizing Telerik's Vue wrappers for Kendo UI. With the TreeView control, both the jQuery version and MVC wrappers have a feature that allows a property to automatically check child checkboxes when the parent checkbox is checked. ...

Launching a Node.js Express application on Heroku

I'm facing an issue while trying to deploy my app on Heroku, as I keep encountering the following error: 2022-08-11T12:49:12.131468+00:00 app[web.1]: Error: connect ECONNREFUSED 127.0.0.1:3306 2022-08-11T12:49:12.131469+00:00 app[web.1]: at TCPConnect ...

Receive a positive or negative data message through Ajax Response

Exploring Ajax for the first time, I am eager to incorporate database interaction using AJAX in JQUERY by connecting to a PHP script. $(function() { $.ajax({ type: "POST", url: "response.php", ...

Using CSS and Vue, you can customize the appearance of inactive thumbnails by displaying them

My goal is for a clicked thumbnail to display in color while the others show as grey. The active thumbnail will be in color, and I want inactive thumbnails to appear in grey. Here is what I am trying to achieve: Vue.component('carousel', { ...

Leveraging the power of Auth0 and Prisma in aggregating user data

In my current project, I am developing a Next.js application with Auth0 as the authentication system. Users are authenticated using the standard middleware: import { withMiddlewareAuthRequired } from '@auth0/nextjs-auth0/edge'; export default wi ...

Adding an element to a blank array using Angular

When attempting to add a new item to an empty array, I encounter an error: $scope.array.push is not a function. However, when the array is not empty, the push operation works flawlessly and updates my scope correctly. Just so you know, my array is initia ...

This error occurs when attempting to access the property 'options' of a variable that has not been defined

Having just completed a significant update to an npm package, I am encountering an error in my nuxt config file... I have yet to come across any information regarding the current state of transformAssetUrls (whether it has been deprecated or renamed) Thi ...

Display a div element on the page after 10 seconds of loading

Recently, I managed to get this script working successfully where it fades out within 20 seconds. However, I am looking to modify it so that it takes only 10 seconds to display after the page loads. Any suggestions on what I should change in the code? jQu ...

I used npm to install a package, but for some reason, it's not appearing in

When attempting to install jquery using npm, I entered the following command: npm install jquery However, upon opening the destination folder, it was empty. (The below text was copied from cmd) > C:\Users\mandar\Desktop\Mady> ...

Turn off Appbar padding at the top and bottom

I am looking to create a customized box within the Appbar that spans the full height, as illustrated in the image below: https://i.stack.imgur.com/CFMo0.jpg However, the default Appbar provides padding from all sides to its internal elements, leading to ...

Select a Button to randomly choose another Button

I am currently developing a dynamic Bootstrap OnePage-Website using HTML, CSS, and JavaScript. The highlight of this website is the Team section where users can book appointments with one of three team members by clicking on a corresponding button beneat ...

How can you integrate jquery ajax in WordPress?

Recently, I started learning about jquery and have been following a tutorial on creating instant search using jquery. The tutorial can be found here. Now, I am trying to implement this on my WordPress site, but it seems like things work differently when d ...

struggling to develop a sophisticated 'shopping cart organization' program

I am in the process of creating a database for video spots, where users can view and modify a list of spots. I am currently working on implementing a cart system that automatically stores checked spot IDs as cookies, allowing users to browse multiple pages ...

Display only the relevant search results using ng-show in AngularJS

By utilizing the code below, I am able to filter results where all entries are displayed on the page: <body ng-app=""> <div ng-init="friends = [{name:'John', phone:'555-1276'}, {name: ...

What is the correct method for accessing an array within an object that is nested inside an array within a JSON file in Angular?

In my Angular controller code, everything is functioning properly except for the $scope.Product. I am unable to access the array of product details. Here is the relevant code snippet: .controller('aboutCtrl', function ($scope, aboutService) { ...

Learning how to implement server side rendering in React JS through tutorials

After diving into the world of React js and mastering the basics, I successfully created web pages using this technology. I also honed my skills with node js and express. However, now I am faced with a new challenge: server side rendering. The tutorials av ...

Is it possible to conditionally call the Apollo Client in my Vue template script?

I have a scenario where I pass a query to the apollo client in my template file using a script tag. However, I want to find a more efficient way to handle this without having to specify the query every time. My idea is to pass a boolean value through a pro ...

Using v-model with the input type files in Vue.js allows for easy two

Is there a way to retrieve data from v-model array in an input type of "file" that allows multiple selections? <input type="file" multiple v-model="modFiles[index]"> <input type="file" multiple v-model="modFiles[index]"> <input type="file" ...

Challenges with compiling Next.js with Tailwindcss and Sass

I recently created a simple template using Tailwind for my Next.js project. Normally, I rely on Tailwind's @layer components to incorporate custom CSS styles. However, this time I wanted to experiment with Sass, so I converted my globals.css file to ...