Image not found when using the stenciljs bundle

3k views Asked by At

I have this stenciljs component which uses an svg images like this:

...
return (
  <button>
    <img src="../../assets/icon.svg"/>
    <slot/>
  </button>
);
...

My folder structure is

src/
    assets/
           icon.svg
    components/
              button/
                     button.tsx

Now, when I do stencil build it creates the dist folder with everything in it.

I copy the dist folder into my site, which has the following structure:

my-web/
       index.html
       bundle/
              <content from dist>

And inside the index.html I load the bundle

<script src="/bundle/my-componets.js"></script>

This works as expected but the asset is loaded from /assets/icon.svg which does not exist (404). Any suggestions what I need to do to fix this?

2

There are 2 answers

1
Abhishek Anand On

From what you intend to do, I understand your goal is to have fully runnable standalone application inside ./dist after build.All sourcefiles which are needed to run the application should be placed there.

This means you will need to create a copy of the sourcefiles (staticfiles) into the distribution folder in the way my-web/assets/icon.svg in order for the application to locate and access it.

0
Schadenn On

There are two ways to do this I guess.

First: Take a look at https://stenciljs.com/docs/config#copy. Using this config setting you can copy your assets (.svg files & whatever) to your dist folder. You can also specify a destination for the files to be copied to, like:

copy: [
    { src: "../path/to/the/files", dest: "./path/to/paste/the/files" }
  ],

Second: Import the asset to the JS of your component. You'll need a Rollup Plugin to handle the import (example: rollup-plugin-svg-to-jsx - but there are others). After setting this plugin up, you can just do:

import * as Icon from "path/to/your/svg"

...

return (
  <button>
    <Icon />
    <slot />
  </button>
);

The first one will keep your JS bundle a little smaller and load the Icon.svg file when you place the button somewhere on the page. The second one will bundle the svg into your JS and load together with your JS - so there is no Button without the Icon at any times.