How to expose Shoelace icons in a Vite app?

703 views Asked by At

The PWABuilder starter comes with Shoelace, which has a library of icons, but they don't seem to work out of the box:

import '@shoelace-style/shoelace/dist/components/icon/icon.js';

@customElement('app-index')
export class AppIndex extends LitElement {

  // ...
  render() {
    return html```
      <sl-icon name="0-circle-fill"></sl-icon>
    ```;
  }

shows an empty icon.

The Shoelace doc mentions the need to configure the bundler and basePath but doesn't come with an example of Vite config.

The icons in question are all bundled in the Shoelace package in node_modules: node_modules/@shoelace-style/shoelace/dist/assets/, so I guess it's just a matter of configuring Vite to make those accessible as public assets, but it's really not obvious how.

How to make Shoelace icons work with Vite? More generally, how to make node_modules assets accessible to a Vite-bundled app?

2

There are 2 answers

1
ejoubaud On

Found a way using the vite-plugin-static-copy plugin:

npm i -D vite-plugin-static-copy

Then in ./vite.config.ts, add the following viteStaticCopy entry at the top of the plugins: array:

import { viteStaticCopy } from 'vite-plugin-static-copy'

// ...

export default defineConfig({
  // ...
  plugins:
    // ADD THIS
    viteStaticCopy({
      targets: [
        {
          src: 'node_modules/@shoelace-style/shoelace/dist/assets/icons/*.svg',
          dest: 'shoelace/assets/icons'
        }
      ]
    }),
    // ...

This will make your icons available in /shoelace/assets/icons/.

Then in your JS code, e.g. in src/app-index.js, add:

import { setBasePath } from '@shoelace-style/shoelace/dist/utilities/base-path.js';
setBasePath('/shoelace');

This will tell Shoelace to look for those assets in /shoelace.

0
koma On

This worked for me :

import { setBasePath } from '@shoelace-style/shoelace/dist/utilities/base-path.js';

setBasePath("https://cdn.jsdelivr.net/npm/@shoelace-style/[email protected]/cdn/");