83

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?

5
  • 4
    Check where the pictures are located in the dist folder. You should never access the src folder, it won't be available in production builds anyway. Commented Mar 15, 2017 at 6:26
  • 1
    That would make sense. However, if I reference the dist folder it would give me an error as dist folder does not exist until I run ng build --prod. Commented Mar 15, 2017 at 6:28
  • 1
    use relative path with ref to your css in your dist.. try ../assets/home-page-img/header-bg.jpg . Thats what works for me in my ionic 2 project.. Commented Mar 15, 2017 at 6:30
  • 1
    try background-image: url('../../assets/home-page-img/header-bg.jpg'); Commented Mar 15, 2017 at 7:15
  • @Thyagu That worked! Thanks. Please provide as answer and I can vote for it Commented Mar 15, 2017 at 7:22

11 Answers 11

130

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">
Sign up to request clarification or add additional context in comments.

8 Comments

This is what I had to do--when I moved the image styling to a scss sheet in a "styles" folder (out of the component's scss file). I kept getting compile errors until I switched to double quotes and just started the path from "/assets/...."
I use SCSS set the backgorund-image to url(/assets/...), when I build doesnt show error, but in the WebStorm IDE shows this error cannot resolve file... I tried '...' and "..." but still geting the red underline. Any idea to remove the annoying error?
Or just background-image: url('~assets/img/background.svg');
This should be the accepted answer, it covers CSS and html usage as well and it is an absolute path, so you don't have to change it when you move your source files.
It does assume, however, that the app and it's assets will be served under / and not some subdirectory.
|
91

try

background-image: url('../../assets/home-page-img/header-bg.jpg');

5 Comments

It really helped.
It's better use @samuel-ivan (stackoverflow.com/a/48890991/10447654) answer as it uses absolute path, it will not depends on your folder structure.
@huanfeng No, you might have an error if the path is incorrect
This results in Angular duplicating the assets and placing them into the root :(
This works always, even if the assets are not served under / but are instead served under a subdirectory - however, the answer from Aarji George is more succinct '~src/assets/...'
37

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" />

2 Comments

Great! I was just looking for this. I'm also using i18n
I am using --base-href and this was the only one that worked with base-href and also without it.
20

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)

3 Comments

Hi @gidon, many thanks fr your explanation. But if our assets are served from a subfolder, how do we have to configure url in the css, in order to have it loaded from the subfolder, and having the image not copied twice in the dist folder?
@lincetto In the css file always start with a slash. So if the image is in assets/some_subfolder the path would be: background-image:url(/assets/some_subfolder/someImage.png);. If you want a folder in a different location you can edit the assets property in angular.json, and point to that folder from css with a slash.
Currently the resulting image file path will have its hash added while processed which enables you to set up infinite caching for it.
15

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');
}

2 Comments

Not sure why this is not the number one answer.
~src/assets/ also solved my IDE errors
11

@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

1 Comment

That's the only way that worked for me in Angular 11 as I have a base-href put for the server and I am developing without it in local, so I needed a relative path. Works with both cases.
7

Everyone's missing one thing base-href.

2 Ways:

  1. background-image: url("^assets/img/bg.svg"); [TLDR; just use this]

This will work even if its going to be deployed in a subdirectory rather than root (i.e. you specify a base-href other than the default /).

  1. background-image: url("../assets/img/bg.svg"); [Using relative path]

Using the relative path from the current css,scss,sass file to the actual image in the project folder like. This will work if the assets folder is 1 level above in the directory tree. ("../../" for 2 levels and so on..) Using a different base-href will not work with this one.

Also, in the build; for the first case this file will be used:

dist/app-name/assets/img/bg.svg

and for the second case the same file will be copied over to the app-name directory and used from there (causing unnecessary redundancy if you already have src/assets in the build assets array in angular.json, which you will in most cases):

dist/app-name/bg.svg

Reference: GH Issue

Comments

3

Try to use this below:

background-image: url('./../assets/home-page-img/header-bg.jpg');

Comments

3

Angular 9+ This Works for me.

.main-bg{
  background-image: url("src/assets/main-bg.png");
}

Comments

2

My problem was solved by:

background-image: url(~src/assets/images/foo.png) .

the same with Hieu Tran AGI

Comments

1

You should fix to the file path. My problem was solved:

background-image: url('../assets/img/logo.jpg')

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.