Angular CLI: Different ways to include assets

Angular CLI: Different ways to include assets

In this article I will discuss several methods of adding and referring to static files in an Angular CLI application – may they be images, fonts or scripts:

  • when the assets are in the assets folder
  • when the assets are in any other folder
  • when the assets are in the node_modules folder

Assets from the assets folder

project
├───src
│   ├───app
│   │   └───app.component.html
│   │
│   └───assets
│       └───logo.png
│
└───angular.json

This is the simplest case. Just add files to the assets folder and refer to them using assets/file path:

Add file src/assets/logo.png
Add the following line to src/app/app.component.html:

HTML
src/app/app.component.html

This is the contents of the dist folder after building:

Note: I'll soon be sharing short, practical tips on Angular — a good way to pick up something new if you're interested.

dist
└───our-application
    ├───assets
    │   └───logo.png
    │
    ├───index.html
    └───...

Assets from other folders

project
├───src
│   ├───app
│   │   └───component1
│   │       ├───assets
│   │       │   └───icon.png
│   │       └───component1.component.html
│   │
│   └───assets
│
└───angular.json

Let’s assume we want to keep assets close to their usage. Let there be a component that has an icon, and we don’t want to put that icon together with all other assets in the global src/assets folder, but instead we want to keep the icon in the same folder as the component.

One option is to include the component’s assets to the assets list in angular.json:

JSON
angular.json

This approach has a disadvantage: after building, the asset will go to app/component1/assets folder in the dist folder:

dist
└───our-application
    ├───app
    │   └───component1
    │       └───assets
    │           └───icon.png
    │
    ├───assets
    │
    ├───index.html
    └───...

Well, it’s not a problem, it just looks ugly. You can still refer to that icon in the component by providing its relative path:

HTML
src/app/component1/component1.component.html

How to make the path look better? Continue reading.

Rename/move assets

The case is the same as previously – we have an asset in an arbitrary application’s folder:

project
├───src
│   ├───app
│   │   └───component1
│   │       ├───assets
│   │       │   └───icon.png
│   │       └───component1.component.html
│   │
│   └───assets
│
└───angular.json

Now we have to fix the generated folder structure. This can be achieved by renaming or moving assets. It can’t be done using simple single line configuration in angular.json, but it’s still easily configurable. We have to use an old inclusion “glob” format.

So instead of single line:

JSON
“assets” in angular.json

write 5 lines:

JSON
“assets” in angular.json

or, equivalently:

JSON
“assets” in angular.json

What does this mean? Look for files matching the glob pattern in the input folder and save them to the output folder in dist under the respective glob name.

Source: <input>/<glob>
Destination: dist/<output>/<glob>

Still unclear? Let’s look at the example:

Copy file "assets/icon.png" from the "src/app/component1/assets" folder and save it to "dist/./assets/icon.png" (simply: "dist/assets/icon.png").

Advice

A glob pattern does not have to be one file. You can use any wildcard characters here, including "*.js" (all .js files) and "**/*" (all files in all subfolders).

In order to refer to that file in an HTML file, link to it using the join of output and glob paths:

HTML
src/app/component1/component1.component.html

Take a look at the generated dist folder:

dist
└───our-application
    ├───assets
    │   └───icon.png
    │
    ├───index.html
    └───...

Include assets from a node module

project
├───node_modules
│   └───jasmine-core
│       └───images
│           └───jasmine-horizontal.png
│
├───src
│   └───app
│       └───app.component.html
│
└───angular.json

If you tried to include an asset from node_modules to the application:

JSON
angular.json

you’ll see an error:

Error: The node_modules/jasmine-core/images/jasmine-horizontal.png asset path must start with the project source root.

Although it is not possible to directly include an asset from outside the source root (in this case – from node_module), to the assets section, there is a workaround using the old style of files inclusion. This is a variation of the previous method (read there for a bit of explanation).

So, instead of creating a line in the section:

JSON
“assets” in angular.json

add the following lines:

JSON
“assets” in angular.json

What does it do?

Copy file "jasmine-horizontal.png" from the "./node_modules/jasmine-core/images" folder and save it to "dist/jasmine-horizontal.png".

In order to refer to that file in an HTML file, link to it using the join of output and glob paths:

HTML
src/app/app.component.html

This is the contents of the dist folder after building:

dist
└───our-application
    ├───assets
    │
    ├───index.html
    ├───jasmine-horizontal.png
    └───...

I don’t really like assets to be mixed with other global files. I suppose it would be better to put that image to the same folder as other assets:

JSON
“assets” in angular.json
HTML
src/app/app.component.html

And this is the contents of the dist folder after building:

dist
└───our-application
    ├───assets
    │   └───jasmine-horizontal.png
    │
    ├───index.html
    └───...

Further reading

Find 3 different methods of retrieving an asset’s content in Angular.

Read next

4.7 22 votes
Article Rating
Subscribe
Notify of
guest
15 Comments
Inline Feedbacks
View all comments
hanatarish@gmail.com
hanatarish@gmail.com
5 years ago

thanks very useful

ajitha
ajitha
5 years ago

can you suggest me some solutions,
I have a table module which is written by our team,we need to make that module work for any angular projects, i have a doubt do i need to get the inputs for icons, font and colors because they vary for different projects. or shall i keep it as static thing

Winnie
Winnie
5 years ago

really useful and clear explanation. Thanks!

SHA
SHA
4 years ago

I am getting an error Data path “” should NOT have additional properties(assets)

Last edited 4 years ago by SHA
geethu
geethu
4 years ago

nice article
Can you please share a general code for this
{
 “glob”: “icon.png”,
 “input”: “src/app/component1/assets”,
 “output”: “assets”
}
I have more than one component which have assets within it. so without specifying each component separately, I would like to write common code using **/. But its not working.
Something like
{
 “glob”: “**/*”,
 “input”: “src/app/**/images”,
 “output”: “images”
}
If I give the exact path, it will be working fine
{
   “glob”: “**/*”,
   “input”: “client/app/shared/header/images”,
   “output”: “images”
}

Last edited 4 years ago by geethu
geethu
geethu
4 years ago
Reply to  Łukasz Nojek

Yes I tried.. but not working
<img src=“images/help-center-icon.svg” alt=“Tasks list”>


{
  "glob": "**/images/*.svg",
  "input": "client/app",
  "output": "images"
}
Denis
Denis
4 years ago
Reply to  Łukasz Nojek

I’ve also tried this and it’s copy files to images folder but also copy files to the root of the app

Last edited 4 years ago by Denis
AngularJS Training in Bangalore
AngularJS Training in Bangalore
4 years ago

Wonderful post! We are linking to this great post on our website. Keep up the great writing.

AngularJS Training in Bangalore
Angular 9 Training in Bangalore
AngularJS Courses in Bangalore
Angular 7 Training in Bangalore

trackback
Why is this image001.png not getting rendered, and how do I fix it? - ErrorsFixing
4 years ago

[…] See here for a good overview of different ways to include assets from different locations: https://lukasznojek.com/blog/2019/03/angular-cli-different-ways-to-include-assets/ […]

Syed
Syed
3 years ago

in ng serve the files from other folders are not getting added to assets folder where as in ng build is working fine.

15
0
Would love your thoughts, please comment.x
()
x