11

I created a simple Angular library and I want my library to also display an image. The problem is that if I include the image inside the module folder of my library and then refer to it from inside the module, I get 404 error. As far as I know, in an Angular project images must be placed inside /assets folder, but I really need to include this image in my library.

I placed the image inside the module folder and refered to it from a the .html file of my module component:<img src="myImage.png">, but it doesn't work.

eli
  • 313
  • 3
  • 6
  • 17

4 Answers4

10

There are several options here, none of which is perfect.

An image can be encoded with base64 to data URLs and used in a template inline:

<img src="data:image/jpg;base64,...">

Or be bound to component property that contains data URL:

<img [src]="imageFoo">

Images can be included alongside with the package, and a user can be instructed to copy them into website public directory. Since public path is unknown beforehand, the module can accept image path configuration with conventional forRoot method and use it for image path:

@Component({
  ...
  template: `<img src="{{imagesPath}}/foo.jpg">`
})
class SomeComponent {
  constructor(@Inject(IMAGES_PATH) public imagesPath: string) {}
}
Estus Flask
  • 206,104
  • 70
  • 425
  • 565
  • "There are several options here, none of which is perfect." Is this still true in 2021? Most of Angular is so good that I'm surprised that including an image in a library component is so awkward. If it's true that a Base64 data URI is still the only way to do this without making the consumer take an extra step, then I'll do it, but if anyone knows of a newer, easier way, please say so. (Thanks for the answer, by the way.) – Gary Sheppard Aug 12 '21 at 12:35
  • 2
    @GarySheppard I didn't revisit this issue for a long time, probably more convenient options are available. I'd try custom image component that dynamically imports image url through file loader, as explained here https://webpack.js.org/guides/asset-modules/ . Can't say if this config works ok with Angular CLI. Some frameworks would go further and do `src` transforms, but this would be too simple for Angular. – Estus Flask Aug 12 '21 at 18:10
0

You can use an encoded base64 image in a template inline as pointed in previous answers, using this option (not tested by me) if you don't have to use the image in more than one place, otherwise your bundle would grow unnecessary.

Or you can "load" the image in the component as a variable and use it in your template using require("./assets/some-file.png") as explained in this post

Note: As Assets coping is not currently supported by ng-packagr when building Angular Libraries, ensure to include assets folder in /dist as explained in this post

LeonardoX
  • 1,113
  • 14
  • 31
-1

See this answer here for bundling images with webpack (which I presume you are using as you have not stated otherwise).

Bundle images with webpack

In short, the image path needs to be relative to the template location:

<img src="../assets/images/myImage.png">
crooksey
  • 8,521
  • 6
  • 30
  • 52
  • I'm not using webpack. Actually, I only added `index.ts` and `package.json` file inside the module I wanted to publish and I ran `npm publish`. – eli Oct 26 '17 at 08:59
  • If you're using the AngularCLI, then this is built on WebPack, and so the principle should still apply. – Guy Park Mar 25 '19 at 15:33
  • 1
    @GuyPark: That's incorrect. Angular Libraries are built with ng-packagr, not with webpack. – Daniel Hilgarth Apr 16 '19 at 12:55
  • Really?? the build process look so WebPack-ish. haha...my bad. I'm sure the principles are very similar though? – Guy Park Apr 26 '19 at 01:18
-3

I am using scss styling and below is the process that I followed.

in scss:

.logo {
       background: url("../../../assets/images/sprite/template.png") 0px 15px;
       width: 90px;
}

in html

<div class="navbar-brand logo"></div>
Eeshwar Ankathi
  • 260
  • 3
  • 11