Angular 2 Load CSS background-image from assets folder
HtmlCssAngularHtml Problem Overview
My folder structure looks like
-myapp
-assets
-home-page-img
-header-bg.jpg
-src
-app
-home-page
-home-page.component.css
-home-page.component.html
-home-page.component.ts
Inside my home-page.component.css, I have the following
header {
width: 200px;
height: 200px;
background-image: url('/src/assets/home-page-img/header-bg.jpg');
}
My angular-cli.json
"assets": [
"assets",
"favicon.ico"
]
When I run the code, I get
GET http://localhost:4200/src/assets/home-page-img/header-bg.jpg 404 (Not Found)
For demonstrating purpose, If I change background-image to the following, I get a whole different error
background-image: url('assets/home-page-img/header-bg.jpg');
./src/app/home-page/home-page.component.css
Module not found: Error: Can't resolve './assets/home-page-img/header-bg.jpg' in '/Users/JohnSmith/Desktop/my-app/src/app/home-page'
How can I get that image to load?
Html Solutions
Solution 1 - Html
I use it. Always starting with "/assets/" in CSS and HTML "assets/". And I have no problems. Angular recognizes it.
CSS
.descriptionModal{
background-image: url("/assets/img/bg-compra.svg");
}
HTML
<img src="assets/img/ic-logoembajador-horizontal.svg" alt="logoEmbajador">
Solution 2 - Html
try
background-image: url('../../assets/home-page-img/header-bg.jpg');
Solution 3 - Html
For background-image: url(/assets/images/foo.png)
, I have another problem with i18n + base-href, finally I found a workaround solution.
My problem was solved by:
background-image: url(~src/assets/images/foo.png)
.
image tag:
<img src="assets/images/foo.jpg" />
Solution 4 - Html
Demystifying Angular paths to resources in CSS files
This is not documented nor has anyone to my knowledge written about it.
This is true for Angular 11 but has certainly been around for a while.
(Note: setting --base-href or --deploy-url in ng build has no consequence to the following).
The regular way to include assets in a css file, such as:
> background-image: url(/assets/someImage.png);
is with a leading slash. During the build prosses (ng serve or ng build), if angular sees that leading slash, It will ignore that path, meaning it will copy it as is. So the browser will see that path '/assets/someImage.png', and will look for that file starting at the root or as we call it domain. (Note: paths in CSS are relative to the location of the CSS file, but even in CSS a leading slash means looking for the file starting form root). Angular assumes you put that file In the default assets folder, who's contents are copied as is to the dist folder, and that sits by default in the root, so someDomain.com/assets/someImage.png just works.
However, if for some reason you are trying to do something else, and you remove that slash, a whole new prosses is happening. For example, lets say you now write
> background-image: url(assets/someImage.png);
without the slash. (for example when you deploy your app to an inner folder in a domain 'someDomain.com/some-folder/', and assets is in that folder. With the slash it will look for assets in the root, and it not there, its in some-folder. So you remove the slash thinking that it will also copy that code as is and look for assets from where the css file is, which is what the browser will do).
Surprise! Angular this time does not ignore that file path!! it looks for it during build time!! and it doesn't fine it, and you get that annoying error saying angular can't find that file. So what you do is rewrite that path until angular can find it (in your file system), for example: if your in a deeply nested component
> background-image: url(../../../../assets/someImage.png);
And then, boom, it works, but take a look at what happened to your dist folder and to your CSS code. Angular makes two copies of the someImage.png file. One in the regular assets folder and the other in the root, right next to all the js bundles. And in you CSS file
> background-image: url(../../../../assets/someImage.png);
will be rewritten to
> background-image: url(someImage.png);
This works, but not exactly nice dist folder structure. This behaver is same for global style.css or component style that gets injected to the index.html or shadowRoot (ViewEncapsulation.shadowDom)
(Note: in the html templates there are no checks or rewrites)
Solution 5 - Html
We can use relative path instead of absolute path:
.logo{
background-image: url('assets/home-page-img/header-bg.jpg');
}
or
.logo{
background-image: url('~src/assets/home-page-img/header-bg.jpg');
}
Solution 6 - Html
Try to use this below:
background-image: url('./../assets/home-page-img/header-bg.jpg');
Solution 7 - Html
Angular 9+ This Works for me.
.main-bg{
background-image: url("src/assets/main-bg.png");
}
Solution 8 - Html
My problem was solved by:
background-image: url(~src/assets/images/foo.png) .
the same with Hieu Tran AGI
Solution 9 - Html
You should fix to the file path. My problem was solved:
background-image: url('../assets/img/logo.jpg')
Solution 10 - Html
@Samuel Ivan's answer does not work for me. Maybe because I am developing an internationalization project. At the end, ^
helps me with
.descriptionModal{
background-image: url("^assets/img/bg-compra.svg");
}
And the answer comes from https://github.com/angular/angular-cli/issues/12797