Reputation: 531
After generating a workspace with the new @angular/cli@18
package, I am unable to determine how to reference image assets placed in the /public
folder.
This did not seem to be an issue with @angular/cli@17
workspaces but they used a different asset folder name & location. v17 created a structure similar to this when using the ng new workspace-name --no-create-application
command and then ng g app application-name
inside that workspace:
workspace-name
|
projects
|
application-name
|
src
|
assets
Then, from a template you could reference an asset like so: <img src="assets/imagename.webp">
However, in v18 the created structure is generated as follows when using commands similar to above:
workspace-name
|
projects
|
application-name
|
public
src
It appears that the assets are intended to go in the public folder but I have tried various permutations of pathing to reference these assets to no avail. Also, doing an ng build [application-name]
does not appear to copy the files in the public folder over to the dist so maybe this has something to do with it.
It should be noted that when an app is generated without a workspace, I am able to reference assets simply by using asset-name.webp
without issue. Additionally, the v18 workspace angular.json
file has the following configuration automatically set for the assets
property of the application build options:
"assets": [
{
"glob": "**/*",
"input": "public"
}
]
Is this a bug with the new builder or is there a new way to reference these assets or some additional configuration that needs to be done now that they are located in a different folder?
Upvotes: 35
Views: 36771
Reputation: 1213
Clarity For the Curious: Flexible Options
While the original question is related to Workspaces specifically (being made up of multiple projects) there are a few simple things that will bring some clarity on what is possible with the management of public assets (published static files). This applies to both Workspaces (multi-project) and to individual projects (library or application).
The change in naming was purely to use a more descriptive naming convention that better describes that the files will be published publicly and not omitted from the build.
In simple terms Angular provides a configuration with maximum flexibility of how you want to manage your public files.
The specification is:
{
"glob": {any valid pseudo-regex "Glob" pattern -- }
"input": {the starting folder to search}
"output": {the destination to copy to in the /dist -- defaults to "/"}
}
Reference Glob Wikipedia
What this means is that all of the following are valid...
Default Config:
{
"glob": "**/*", //copy all files & folders
"input": "public", //start in the public folder
}
Builder Transposition:
public/landing/cool-book.jpg => landing/cool-book.jpg
public/download.pdf => download.pdf
Example templates reference:
<a href="/download.pdf">
<img ngSrc="landing/cool-book.jpg"/></a>
Example A:
{
"glob": "**/public/**/*", //copy any file in any 'public' folder
"input": "src/app", //start in the src/app folder
}
The builder would ignore your root /public folder in this case without the default angular.json asset configuration generated by "ng" and instead look for folders under src/app
src/app/my-component/public/some-folder/logo.jpg => my-component/public/some-folder/logo.jpg
src/app/shared/nav-bar/public/house.svg => shared/nav-bar/public/house.svg
Example template reference:
<img ngSrc="my-component/public/some-folder/logo.jpg"/>
Example B:
{
"glob": "**/*.jpg", //publish only JPGs
"input": "public", //start in the root 'public' folder
"output": "jpg-files"
}
The builder would only look at the root /public folder (similar to default angular.json asset configuration generated by "ng") and further limit to files ending in .jpg and lastly would output them to a new folder called jpg-files
public/some-folder/logo.jpg => jpg-files/some-folder/logo.jpg
public/shared/nav-bar/public/house.svg => (not copied)
Example template reference:
<img ngSrc="jpg-files/some-folder/logo.jpg"/>
Example C:
{
"glob": "**/*",
"input": "public", //start in the root 'public' folder
"output": "public" //publish to 'public' folder
}
This just changes the default angular.json configuration to put the assets in a folder called public in the dist build copy instead of in the root.
public/some-folder/logo.jpg => public/some-folder/logo.jpg
public/shared/nav-bar/public/house.svg => public/shared/nav-bar/public/house.svg
Example templates reference:
<img ngSrc="public/shared/nav-bar/public/house.svg"/>
Upvotes: 0
Reputation: 931
With Angular 18 and later versions, you have the flexibility to either move your static images to the public
folder or continue using the src/assets/images
directory by adding it to the angular.json
configuration file. Here's how to do the latter:
angular.json
"assets": [
{
"glob": "**/*",
"input": "public"
},
{
"glob": "**/*",
"input": "src/assets/",
"output": "/assets/"
}
]
Asset/Image location:
/src/assets/images/my.jpg
Example HTML:
<img src="assets/images/my.jpg" />
Upvotes: 1
Reputation: 383
In Angular 18 the structure for referencing assets has changed and assets are now managed inside the public folder, earlier assets were placed under the src/assets
directory.
In latest version angular, the angular.json
configuration automatically includes the necessary setup for the public
folder, so you don't need to manually configure it. By default, Angular will look for assets in the public directory during the build process.
Step 1: Place all your assets like images, videos, fonts, etc., inside the public folder like given below
public/
└── assets/
└── images/
└── ai-loading.gif
Step 2: In your component.html you can reference these assets directly using the path starting from assets.
<img src="assets/images/ai-loading.gif" id="loader-image" width="300px" />
Since Angular serves the public folder at the root level, so you don't have to specify /public/
in the path just start from assets/
.
Upvotes: 0
Reputation: 41
I had the same issue today when starting a new Angular 18 project. It seems Angular looks for images in the /public/assets folder.
I used an absolute path in the img tag like this: src="/assets/image.png"
, and it worked for me. Other path options didn't work.
Upvotes: 4
Reputation: 97
In case that helps anyone (because it took me some time):
If you're trying to reference a locally hosted font in a .css, you need to reference it with an absolute path and don't forget the ^
at the beginning of the path.
In this case, my .css is in src/
and the config for the font in public/fonts
looks like this:
@font-face {
font-family: Inter;
src: url('^./../../public/fonts/Inter-VariableFont_opszwght.ttf') format('truetype');
}
Upvotes: 1
Reputation: 520
I had the similar issue few days back at Angular 18.2. After creating 'assets' folder under 'public' folder it works for me. If still not working for you just run the 'ng serve' or 'ng dev' command again.
<img src="/public/assets/logo.png" alt="logo" />
Upvotes: 0
Reputation: 51
I use Angular 18.2.8 version. I tried multiple things and in the end it worked. It's important to know that the public folder is created by angular and it's in the same folder as src folder. The folder stucture is this:
src
public
|images
|Product_01.jpg
In the end it worked with this path:
<img src="images/Product_01.jpg">
I did not modified angular.json. This contains:
"assets": [
{
"glob": "**/*",
"input": "public"
}
]
Upvotes: 0
Reputation: 2256
This is the angular.json assets array. It does not have to be modified.
"assets": [
{
"glob": "**/*",
"input": "public"
}
]
Just put your images folder in the public folder of your application. In my case my images are in public/assets/img. angular.json does not have to be modified.
I reference my images like so:
<img src="assets/img/{{img}}">
Upvotes: 1
Reputation: 111
I was building a new mfe federation host and remote, remote worked perfectly fine, but the host app had issues loading federation.manifest.json, looks like angular 18 by default angular does not move public assets on dev, in this case we should set the output option under assets array in angular.json file.
"assets": [{
"glob": "**/*",
"input": "projects/host/public",
"output": "public"
}],
Upvotes: 0
Reputation: 726
In angular 18 public folder config in angular.json
"assets": [
{
"glob": "**/*",
"input": "public"
}
]
for example to load logo.png in "public/img/logo.png" just remove public/ in url.
<img src="img/icon.png" />
Upvotes: 29
Reputation: 1
You just need to put assets folder in correct order,as mentioned in the following
to add in src of img tag
use this
'assets/...'
Upvotes: -2
Reputation: 51
solution to image in angular 18:
in angular 18 version there is not "assets" folder. if you want to put in your project images, you put the images in the "public" folder and not in the assets folder and you will write in the src of the img the name of the image without any routing.
for example:
if this is the name of the image:
"2.JPG"
so you write in the img tag:
< img src="2.JPG" alt="">
and you dont have to write all the route.
i hope i helped and it will be usefull.
Upvotes: 5
Reputation: 323
Me too, I initially had only the /public folder (no /assets folder created by "ng new project-name", Angular CLI 18.0.2), and couldn't load images from /public.
I had to create the "assets" folder myself under "public": /public/assets (and I placed my image here).
Then, <img src="/assets/test.png">
worked.
Upvotes: 12
Reputation: 531
After doing a little investigating it looks like the @angular/cli
did not set the projects.applicationName.architect.build.assets
property in the angular.json
file properly. Changing over the input
property from public
to projects/applicationName/public
did the trick. Now I am able to reference assets simply with asset-name.webp
.
I have opened an issue on the @angular/cli
repo with regard to this so hopefully someone there can address this problem.
Upvotes: 8