x
)- [ ] bug report -> please search issues before submitting
- [ x ] feature request
@angular/cli: 1.0.1
node: 8.0.0
os: darwin x64
@angular/animations: 4.1.3
@angular/common: 4.1.3
@angular/compiler: 4.1.3
@angular/core: 4.1.3
@angular/forms: 4.1.3
@angular/http: 4.1.3
@angular/material: 2.0.0-beta.6
@angular/platform-browser: 4.1.3
@angular/platform-browser-dynamic: 4.1.3
@angular/router: 4.1.3
@angular/cli: 1.0.1
@angular/compiler-cli: 4.1.3
Related to https://github.com/angular/angular-cli/issues/4517#issuecomment-286252628
The CLI transform the HTML as well
I am using S3
on AWS this is kind of required for me unless I used CloudFront
, I think.
+1 for this
@Brocco could we do something like i18n
for the URL on the HTML, because I can see the big issues on it (no everything have to be href
or src
) but we could use the same strategy in the worse scenario.
This is something I'd like to have if we can find a safe way to do it. For reference, there's some more context in https://github.com/angular/angular-cli/issues/4517#issuecomment-326970581.
Any update here?
how to fix it?
+1 fix it please!
i have an app with different base href and the sass is compiling correctly the routes but not in html link, src, etc
it's not only inconvenient, the code won't work.
I'm using ng5 now. My workaround is to add a prefix {{baseHref}}
of each src in HTML template.
<img src="{{baseHref}}/assets/sample.png">
@RSginer
@timelyxyz thank you so much! this is a possible solution but you need to create a local variable in each component or it is a global variable?
@timelyxyz this does not work for AOT :(
This is horrible.
pipe this plz, æˆ‘çš„æ‰‹éƒ½å¿«åŠ ç´¯æ»äº†ã€‚
Best solution for now is to use the background-image css property. The cli will add the base href attribute to this.
Also you could define the url in your environments.ts file and import it into your components.
Workaround until Angular takes the effort to fix, is to add a property to your environment variable, like deployUrl: '/xyz/', then for all 'assets' objects, you can add the following logic in html:
<img src="{{getEnv().deployUrl}}assets/img/logo.svg">
For i18n, I used a custom loader.
I went through the code of the Ivy rendering engine, compilers and CLI.
The main problem is that the url(...)
replacement in the css files are done by webpack. The Html template is parsed by Angular compiler.
I think an AssetUrlVisitor could solve this problem. It should add the route as string concat. That would make img[src]
attribute work without any binding. If it has binding the url should be added before the interpolation runs.
The visitor should look for img with src and make the changes to it. Probably there are more scenarios for example src-set for the future. Extension with the visitor would be easy. (Ivy is really great!)
The new url config should have a new name, so it could be introduced without breaking changes. E. g. assetUrl. Then in later versions could be merged with deployUrl.
The policy how to change the links could be the same as the algorithm made by webpack, for the best consistency.
Hi,
I have a hybrid app. Not just angular hybrid, but a lot of stuff. So my deployUrl is virtual directory in IIS. I can not, or couldn't figure out how to, change baseHref, because for the page url '/' is just the base i need.
I have pretty much the same setup on dev machine as on server. So I could fix the assets paths thing by adding deployUrl to my src attributes, which is... yes on of those "fixes".
However now, I'm using storybook and it doesn't have to know about deployUrl, so all my assets are 404.
Is there way to make it work without touching baseHref?
One quick note - if, after build, the assets are located in the base folder of index.html, you can use relative paths to access them by prefixing with ".":
<img src="./assets/img/logo.svg">
This seems to be working with the baseHref build flag, since the path is relative.
My workaround is to use nginx router rewrite.
nginx.conf:
location /assets/ {
rewrite ^/assets/(.*)$ http://cdn.example.com/path/assets/$1 redirect;
}
Has someone discovered any workaround to this?
I don't want to append baseHref
to all my images in HTML templates. I am playing around with custom webpack configuration, but nothing seems to be working as of now.
Has anyone seen any progress with a custom Webpack configuration or anything for that matter?
A web browser will use the configured HTML base HREF value with all relative URLs. As long as relative paths are used with a properly configured base HREF value, no custom configuration should be required.
The deploy URL option is entirely different and is best avoided where possible as it hard codes the path within the application (potentially in multiple locations). An alternative for deploy URL that covers many situations is to use a combination of an HTML base HREF (with potentially not having one) and the Angular APP_BASE_HREF
token (docs). The later of which controls the base URL for the Angular router which will otherwise default to the HTML base HREF.
@clydin
I want to serve images from a CDN and the rest of the app should point to /
. Will your solution help me achieve that?
I tried setting APP_BASE_HREF
to cdn.example.com
and now my app automatically redirects to localhost:4200/cdn.example.com
. Is this the expected behaviour?
No real work arounds for hosting index.html
on domain A and all the assets/JS on Domain B?
Even doing search/replace won't work as some of the asset paths are inside component source files.
Really, if Angular CLI could just expose the value of deploy-url and replace it at build time would work.
Our Angular app is 40+ meg and I don't really want to go through all the URLs in our source code and manually update them...
This need to be fixed urgently. Don't you developer guys use CDN? Angular is really a outdated framework. @filipesilva
In my case I had to change my src
from
<mdb-card-img src="../../assets/404.png"></mdb-card-img>
(which was correct from src/app/component_dir
) to
<mdb-card-img src="assets/404.png"></mdb-card-img>
and ng serve
properly used the path of http://localhost:4200/{deployUrl}/assets/404.png
As a workaround, we change
<!-- component.html -->
<img src="assets/arrow-left.png" />
to something like this
// component.ts
const arrowLeft = require('assets/arrow-left.png');
export class MyComponent implements OnInit {
readonly arrowLeft = arrowLeft;
}
<!-- component.html -->
<img [src]="arrowLeft" />
By requiring the image in ts, the file can be correctly loaded by file-loader, and so both file hash and deploy-url work. This pattern is also very common in React world.
A potential workaround that worked for us, can be found here, too: https://stackoverflow.com/a/46493276/1902598
Basically set APP_BASE_HREF
with the help of the PlatformLocation.getBaseHrefFromDOM
I recently also ran into the same situation because of https://github.com/angular/angular-cli/issues/15295#issuecomment-520098529.
After trying a couple different ways, a solution I found that suits me well is using different assets
in angular.json
for production
: https://angular.io/guide/workspace-config#asset-config (the "asset specification object" part)
@clydin is it possible to configure the APP_BASE_HREF from the angular.json file?
I would like to configure the two different baseHref and appBaseHref in the same place and from configuration.
Is there any way to decouple APP_BASE_HREF
provider from --base-href
somehow?
That way for the browser, it could respect the HTML tag for all relative static assets, lazy-loaded chunks, etc
<base href="http://www.somecdn.com/"/>
But for Angular router, configuring the provider to have it respect a different "root" so routing doesn't break, based on what is in the user's URL bar ex:
providers: [
{
provide: APP_BASE_HREF, useValue: `/` // or even `${window.location.origin}/`
}
]
In this way, we can use a CDN for all our lazy chunks assets, but not breaking routing, which would be URL / hostname based.
So just curious to know from the maintainer's point of view, if there is a way forward through some sort of enhancement to Angular and / or the CLI (whether it's this idea or something completely different)?
If so, I would be happy to take a look into implementing such a feature, opening an issue for discussion, and contributing. Just want to make sure there is a path forward and would then be happy to put some time into working on it.
Thanks!
Here's my workaround:
declare const __webpack_public_path__: string;
export function deployUrl(url: string): string {
let publicPath = __webpack_public_path__;
if (!publicPath.endsWith('/')) {
publicPath += '/';
}
if (url.startsWith('/')) {
url = url.slice(1);
}
return `${publicPath}${url}`;
}
In component:
@Component({...})
export class MyComponent {
deployUrl = deployurl;
}
In template:
<img [src]="deployUrl('assets/image.png')"/>
As there is an awful lot of confusion around --deploy-url
I think this is a good candidate to review and update documentation. Specifically this could include:
--deploy-url
is intended for (and what it is not).--deploy-url
or other means) makes the most sense and does what an application wants./cc @aikidave for visibility.
Copied from my STACKOVERFLOW answer. Its a very annoying problem: Here is how I solve it:
When your app is for e.g. hosted under
www.domain.de/hehe
.
angular.json
add "deployUrl": "./",
src/index.html
inside <head>
add/update <base href="./">
<img src="./assets/img/pictureOfMyCrazyWife.png">
ng build
or ng build --prod
conveniently.Hope this helps and saves some grey hair, couse it only looks good on George Clooney.
@andreElrico that does not seem to work if you are using routing
If you try to navigate from the base path, let's say /base-path/
to /base-path/router-path
then try to reload the page or copy the link to another tab, the application will fail to load since it tries to use /base-path/router-path
as base path
@CaselIT have not tried it with routing.
The problem of not being to add cache-busting hash to images used in Angular templates is a production issue many are dealing with.
I understand that this is out of scope for the CLI team at the moment, but I have seen some workarounds. I will try to summarize what i've seen so far.
If you want image cache-busting / fingerprinting you have these options:
<img>
tag in template.I think it will be very helpful for the community if we had a "blessed" workaround for this from the cli team and get their view on this. Ideally added to the official cookbook/recipe/docs
Thank you
@filipesilva I want to second @mderazon idea about having a "blessed" solution for this. It seems like the community is wasting a lot of time on something that is pretty common. I'd be willing to help with a solution, but I think we are looking to you guys for a little direction as to what you think should be done or info if you are already working on something.
I don't know if it is the same issue, because I use command --base-href of Angular.
But if it helps someone, I'm happy.
I used the \ before the assets like this:
<img [src]="'\assets/images/image.png'"/>
And this worked perfectly for me.
Most helpful comment
This is horrible.