Webpack compilation results in missing SVG icons display

As a newbie in web application development, I find myself in the final stages of my project. My current challenge involves bundling the entire project using webpack, and it's mostly smooth sailing except for one hiccup with my SVG icons.

The issue seems to lie in how webpack references the SVGs in the compiled index.html file.

In the original index.html, SVGs are referenced like this:

<svg role="img">
   <use href="images/icons.svg#settings-icon"></use>
</svg>

However, in the compiled index.html, the reference appears as follows:

<svg role="img" style="margin-bottom:-3px">
   <use href="aaf2f945f2b181c45647.svg#settings-icon"></use>
</svg>

After compiling, the structure of my dist/ folder looks like this:

dist/
├── images/
│   └── icons.svg
├── aaf2f945f2b181c45647.svg
├── bundle.js
└── index.html

The content of aaf2f945f2b181c45647.svg is as follows:

export default "images/icons.svg";

The file icons.svg contains all my SVGs as expected.

Replacing "aaf2f945f2b181c45647.svg" with "images/icons.svg" in the compiled index.html resolves the issue for me. However, I'm puzzled as to why webpack navigates to icons.svg via aaf2f945f2b181c45647.svg in the first place. Is there a way I can instruct it to directly write "images/icons.svg" into the HTML file?

Here is an excerpt from my webpack.config.cjs:

/* webpack configuration file */
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');

module.exports = {
    entry: './frontend/src/scripts/index.ts',
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'frontend/dist'),
        clean: true,
    },
    module: {
        rules: [
            /* various rules here */
        ],
    },
    resolve: {
        extensions: ['.ts', '.js'],
    },
    plugins: [
        new CleanWebpackPlugin(),
        new HtmlWebpackPlugin({
            template: './frontend/public/index.html',
            filename: 'index.html',
        }),
    ],
};

This is the breakdown of my folder structure:

dist/
├── images/
│   └── icons.svg
├── aaf2f945f2b181c45647.svg
├── bundle.js
└── index.html

public/
├── images/
│   └── icons.svg
└── index.html

src/
├── scripts/
│   └── ...
└── styles/
    └── ...

I have attempted using url-loader, svg-url-loader, and svg-sprite-loader without success in displaying my SVGs.

Answer №1

Instead of neglecting the power of html-loader when it comes to handling HTML files, why not leverage it for ensuring that use tags are processed accurately? Additionally, consider updating the settings of file-loader to effectively handle SVGs within HTML like so:

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');

module.exports = {
    entry: './frontend/src/scripts/index.ts',
    output: {
        filename: 'bundle.js', 
        path: path.resolve(__dirname, 'frontend/dist'), 
        clean: true,
    },
    module: {
        rules: [
            {
                test: /\.ts$/,
                use: 'ts-loader',
                exclude: /node_modules/,
            },
            {
                test: /\.css$/,
                use: ['style-loader', 'css-loader'],
            },
            {
                test: /\.svg$/,
                type: 'asset/resource',
                generator: {
                filename: 'images/[name][ext]', 
       },
            },
            {
                test: /\.html$/,
                use: [
                    {
                        loader: 'html-loader',
                        options: {
                            sources: {
                                list: [
                                    '...',
                                    {
                                        tag: 'use',
                                        attribute: 'href',
                                        type: 'src',
                                    },
                                ],
                            },
                        },
                    },
                ],
            },
        ],
    },
    resolve: {
        extensions: ['.ts', '.js'],
    },
    plugins: [
        new CleanWebpackPlugin(),
        new HtmlWebpackPlugin({
            template: './frontend/public/index.html',
            filename: 'index.html', // Output HTML file name
        }),
     ],
};

Answer №2

Employing url-loader in conjunction with webpack is a great way to handle SVG files. By using the following configuration, you can load SVG images efficiently: { test: /.svg$/, loader: "url-loader?limit=10000&mimetype=image/svg+xml" }

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

Capture and transform every alert into a notification

I have implemented Gritter for notifications across my website and am curious if there is an easy method to intercept all alert() messages triggered by scripts using jQuery, and then display the contents of the alert in a Gritter notification. Is there a ...

Using Kendo's Angular Grid to link data sources

I'm currently facing a minor issue with the Kendo Grid for Angular. My attempt to bind data after fetching is resulting in the following error: ERROR TypeError: Cannot read properties of undefined (reading 'api') This indicates that this. ...

`Loading CSS files in Node.js with Express``

My CSS isn't loading properly when I run my HTML file. Even though the HTML is correctly linked to the CSS, it seems like express and node.js are not recognizing it. I find it confusing to understand the articles, tutorials, and stack overflow questio ...

How to Deactivate the Default Selection in React-Select

Having trouble with the focus in a React Select dropdown. The first item always gets focused when opening the dropdown, despite passing various props without success. I checked their GitHub for related issues around autofocus but couldn't find a solut ...

Passing data between pages using React Native hooks

I am a newcomer to React Native and facing challenges in passing data to another page. Specifically, I want to transmit data from the QR Reader to another Page. Below is my code on the first screen: const LoginScreen = (props) => { const onSucce ...

I utilized the `<script src="sample.pdf"></script>` tag in my HTML code and surprisingly, the JavaScript within the PDF document was still able to execute

Recently, I encountered a situation where I included a PDF file with JavaScript code in the src attribute of a script tag in my code. Surprisingly, the JavaScript code executed without any issues. This made me wonder if I can use any type of file extension ...

Get the Google review widget for your web application and easily write reviews using the Google Place API

I developed a platform where my clients can provide feedback and ratings on my services through various social media platforms. Currently, my main focus is on collecting Google reviews using a Google widget/flow. https://i.sstatic.net/RvPst.png The imag ...

The error message I'm encountering is IntegrationError: The stripe.confirmCardPayment intent secret is invalid. The value must be a client_secret string

Currently, I am immersed in a tutorial for creating an Amazon clone using React JS. Everything was going smoothly until I encountered an issue after processing my orders. To handle the payment functionality, I am leveraging Stripe, Firebase, Axios, and Exp ...

Enhancing Angular 5 with CustomEvent Polyfill for JavaScript

After implementing the code snippet in main.ts file, I encountered an issue with CustomEvent not being added to the window object correctly. Strangely, when I manually add CustomEvent using the JavaScript console, it works fine. This problem arises specifi ...

Make an AJAX GET call to an ASP.NET Web API endpoint

Here is the ajax script I am using: $.ajax({ dataType: 'json', url: url, data: tuDispId, type: "GET", success: function (data) { bindData(data); $("#ale ...

Troubleshooting problem with transmitting data using the b4j jQuery WebSocket library

I'm seeking guidance on the process of sending data through a custom library that connects to a Java server operating as a WebSocket server. The code I'm using for successful connection is: <script src="https://ajax.googleapis.com/ajax/libs/ ...

Why is my client program not receiving a response from this socket.io server?

Currently, I am in the process of developing a trivia game where two users engage in answering questions with the winner being declared at the end. As part of this project, I have integrated socket.io to facilitate the exchange of answers. However, I have ...

Dealing with hefty JSON documents using iron-ajax, iron-list, and loading with iron-scroll-threshold

I'm facing an issue while attempting to load a large JSON file into my view that contains over 1000 items. My goal is to have the view import only 20 items at a time. However, every time I utilize iron-list, it only renders 3 items initially until I r ...

I've run into some issues with implementing material UI packages. Can anyone suggest which specific package I should install to fix this error?

Error in compilation. ./src/Component/Form.js Module not located: Unable to find '@mui/icons-material/Login' in 'C:\Users ...

"Utilizing jQuery Mobile's Pagebeforeshow event with the advanced functionality of longlist

Currently, I am utilizing JQuery mobile version 1.0.1. To set up a page, the following code is utilized: <div data-role="page" id="homecomments"> <div data-role="header"> <h1>Comments</h1> <a href='#home&apo ...

Issue with static resource fetching when referencing a .js file within an HTML document while using Flask

My HTML file loads my OpenLayers JavaScript file (which displays a map frame) when opened directly. However, when running the HTML from my Flask python app, the JavaScript file/object fails to load (resulting in no map display, just some heading text). I ...

I'm having trouble persisting my mongoose model data in my MongoDB database

Hey there, I'm new to this and currently attempting to save the Amadeus object I've created into mongosh using the .save() method. However, after connecting to my file through node, editing the Amadeus object, and running amadeus.save(), I check ...

Tips for maintaining a sticky header while continuing to utilize Bootstrap table classes such as table-responsive and table-stripped

This is Here's my code on jsfiddle I've attempted to make the header sticky while maintaining the current layout, but every approach I've tried ends up messing with the responsiveness of the table. My next plan involves using a JavaScript ...

Script for Ajax not working properly

I am facing a problem with my ajax request where it still loads the php script instead of executing its function without refreshing. I suspect there might be an issue with my ajax. Can someone please review the ajax script and point out any errors? HTML ...

Manage the sequence in which the various paths of an SVG element are displayed

Searching for a way to display an image in HTML with a rounded dashed border? Take a look at the example below: https://i.sstatic.net/YrCZS.png The number of dashes and their colors can be controlled, similar to what you see in WhatsApp's status tab ...