Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I insert an image into a Web Component?

I'm trying to insert an image into a Web Component I'm building with Stencil.

I'm getting 2 errors:

AppLogo is declared but its value is never read.

and

Cannot find module ../assets/logo.svg.

Directories:

- src
-- components
--- app-header
---- assets
----- logo.svg
---- app-header.tsx
---- app-header.scss
---- app-header.spec.ts

Code:

import { Component } from "@stencil/core";
import AppLogo from "../assets/logo.svg";

@Component({
  tag: "app-header",
  styleUrl: "app-header.scss"
})

export class AppHeader {
  render() {
    return (
      <header class="app-header">
        <a href="#" class="app-logo">
          <img src="{AppLogo}" alt="App Name" />
        </a>
      </header>
    );
  }
}

There's not a ton of documentation around this (that I can find). So, any help is appreciated.

like image 472
Aaron Benjamin Avatar asked Oct 25 '25 15:10

Aaron Benjamin


1 Answers

Quite some things that went wrong here.

import AppLogo from "../assets/logo.svg";

You can't just import a .svg file into Javascript. What do you expect AppLogo to contain when you import it like that? Normally when you import a .js, .jsx or .tsx file that way, somewhere in those files there is an export specified. So you know when you import from that file, you'll get whatever you exported. There is no export in a .svg though.

Your usage is also wrong:

<header class="app-header">
  <a href="#" class="app-logo">
    <img src="{AppLogo}" alt="App Name" />
  </a>
</header>

First of all get rid of the " around {AppLogo}. You want to use the value of {AppLogo}- not use a string containing {AppLogo}.

Now there are two ways to achieve what you want:

The assets way

Somewhere in the root of your project, there's a stencil.config.ts file. In there you can specify copy tasks. You can read here how to do this: https://stenciljs.com/docs/config#copy

After you set that up correctly and your ../assets/ folder is being copied to your build folder, you can just use the image by putting in the path as the src:

<header class="app-header">
  <a href="#" class="app-logo">
    <img src="./assets/logo.svg" alt="App Name" />
  </a>
</header>

The Rollup way

You can also use Rollup to import it. Stencil is using Rollup as its module bundler. The stencil.config.ts is basically a rollup.config-file. You can find a lot of documentation on rollup here: https://rollupjs.org/guide/en#configuration-files

There are some rollup plugins that support importing .svg files:

  • rollup-plugin-svg
  • rollup-plugin-svgo
  • rollup-plugin-svg-to-jsx

If you use any of those, you'll be able to import your .svg files. Depending on which plugin you use AppLogo will contain something different.

For example rollup-plugin-svg-to-jsx will give you a ready-to-use JSX-tag when importing. So after you do

import AppLogo from "../assets/logo.svg";

You'd be able to use it like:

<header class="app-header">
  <a href="#" class="app-logo">
    <AppLogo />
  </a>
</header>
like image 115
Schadenn Avatar answered Oct 28 '25 05:10

Schadenn