How do I use shoelace.style icons in svelte?

165 Views Asked by At

I can use e.g. the sl-switch tag by following the shoelace.style docs (https://shoelace.style/components/switch):

<script>
    import '@shoelace-style/shoelace/dist/themes/light.css';
    import '@shoelace-style/shoelace/dist/components/switch/switch.js';
<script>

<sl-switch size="small" checked></sl-switch>

To use the icons I'm supposed to set the base path (e.g. https://shoelace.style/getting-started/installation#bundling). My attempt:

<script>
    import '@shoelace-style/shoelace/dist/themes/light.css';
    import '@shoelace-style/shoelace/dist/components/icon/icon.js';
    import { setBasePath } from '@shoelace-style/shoelace/dist/utilities/base-path';
    setBasePath('node_modules/@shoelace-style/shoelace/dist');
</script>

<sl-icon name="android2"></sl-icon>

I'm just starting out with svelte (and frontend frameworks in general) and I've obviously missed a step. The error I'm getting is:

SvelteKitError: Not found: /assets/icons/android2.svg
    at resolve (C:/srv/svelte/yoda5/node_modules/@sveltejs/kit/src/runtime/server/respond.js:494:13)
    at resolve (C:/srv/svelte/yoda5/node_modules/@sveltejs/kit/src/runtime/server/respond.js:294:5)
    at #options.hooks.handle (c:/srv/svelte/yoda5/node_modules/@sveltejs/kit/src/runtime/server/index.js:71:56)
    at Module.respond (C:/srv/svelte/yoda5/node_modules/@sveltejs/kit/src/runtime/server/respond.js:291:40)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
  status: 404,
  text: 'Not Found'
}

I've added the rollup.config.js file (https://github.com/shoelace-style/rollup-example/blob/master/rollup.config.js):

import path from 'path';
import commonjs from '@rollup/plugin-commonjs';
import copy from 'rollup-plugin-copy';
import css from 'rollup-plugin-css-only'
import resolve from '@rollup/plugin-node-resolve';

export default {
  input: 'src/index.js',
  output: [{ dir: path.resolve(__dirname, 'dist'), format: 'es' }],
  plugins: [
    resolve(),
    commonjs(),
    // Bundle styles into dist/bundle.css
    css({
      output: 'bundle.css' 
    }),
    // Copy Shoelace assets to dist/shoelace
    copy({
      copyOnce: true,
      targets: [
        {
          src: path.resolve(__dirname, 'node_modules/@shoelace-style/shoelace/dist/assets'),
          dest: path.resolve(__dirname, 'dist/shoelace')
        }
      ]
    })
  ]
};

but it doesn't seem to be run on either npm run dev or npm run build..?

I'm using svelte5 if that matters.

1

There are 1 best solutions below

0
On

Ok, something weird definitely goes on with this one. If you open this sveltelab example I just created, it may or may not work. It seems that on opening it, you get the error you mention.

Now comment the setBasePath() call. Immediately the icon shows up.

Now uncomment the line. The icon still shows up. It is pretty much the same code you have:

<script>
    import Counter from '$lib/Counter.svelte';
    import '@shoelace-style/shoelace/dist/components/icon/icon.js';
    import { setBasePath } from '@shoelace-style/shoelace/dist/utilities/base-path.js';
    export let data;
    setBasePath('node_modules/@shoelace-style/shoelace/dist');
</script>

<h1>
    Hello {data.name}!
</h1>

<Counter />

<p>
    Learn more about templates at
    <a href="https://docs.sveltelab.dev/templates" target="_blank"> docs.sveltelab.dev/templates </a>
</p>
<sl-icon name="android2" />

So, the learning: It might be an issue with Svelte's HMR, SvelteKit or something else. The fact that it ends up working seems to tell us that the code is correct, and even that the call to setBasePath() might not even be needed.

Experiment a bit more to see if you discover something else. For example, instead of using a SvelteKit project, do a Vite + Svelte project using the command npm create vite@latest.

Finally, I know this is not an answer, but I could not possibly fit all this in a comment. Stop the hate. :D