Svg for extension icon

I am trying to use an svg for the side bar icon in my extension. However it seems like webpack is formatting the svg as a javascript module? Any ideas on how to fix appreciated!

File structure

I have the svg in /style/logo.svg and my package.json is referencing this file.

 "files": [
    "lib/**/*.{d.ts,eot,gif,html,jpg,js,js.map,json,png,svg,woff2,ttf}",
    "style/**/*.{css,js,eot,gif,html,jpg,json,png,svg,woff2,ttf}"
  ],

Error

However the packed svg in extensionName/labextension/static/random_string.svg not valid and looks like this:

module.exports = "data:image/svg+xml,%3csvg width='500' height='450' viewBox='0 0 500 450' fill='none' xmlns='http://www.w3.org/2000/svg'%3e %3cpath class='jp-icon3' fill-rule='evenodd' clip-rule='evenodd' d='M296 0H203V450H296V0ZM101 141H195V450H101V141ZM0 214H93V450H0V214ZM304 79H398V450H304V79ZM500 205H407V450H500V205Z' fill='%23616161'/%3e %3c/svg%3e"

If I manually copy and paste in the valid svg (below), then it works.

Correct icon.svg

<svg width="500" height="450" viewBox="0 0 500 450" fill="none" xmlns="http://www.w3.org/2000/svg">
<path class="jp-icon3" fill-rule="evenodd" clip-rule="evenodd" d="M296 0H203V450H296V0ZM101 141H195V450H101V141ZM0 214H93V450H0V214ZM304 79H398V450H304V79ZM500 205H407V450H500V205Z" fill="#616161"/>
</svg>

How can I fix the build process to copy over the svg correctly?

Ok I figured this out, webpack was actually working fine I had to change how I was using the svg.

In /src

Add new file svg.d.ts

declare module '*.svg' {
  const value: string;
  export default value;
}

Then I was using the svg as my icon for a stackedpanel, so had to import it and use like this:
./src/Panel.ts:

import appIconStr from "../style/logo.svg"

export class MyPanel extends StackedPanel {
    constructor() {
        super();
        // other setup
        this.title.caption = 'myextension'; // shown on hover

        const icon = new LabIcon({
            name: 'myextension:app-icon',
            svgstr: appIconStr,
        });

        this.title.icon = icon
     }
    // rest of panel
}
1 Like