My app is going to be used on multiple machines, and it may be located in a different place each time. For example, the home route may be at any of the following locations:
localhost:9000/home
localhost:9000/abc/home
localhost:2000/yet/another/location/home
So I want to make sure my app will work no matter where it needs to find its assets. All my paths are relative, so hopefully that's a step in the right direction, like this:
<link rel="stylesheet" href="assets/global-styles.css">
and in my component templates, like this:
<img src="assets/components/dashboard/images/foo.png" />
Here's what I've tried so far:
I've modified my <base>
attribute so manually grab the part of the URL after the port and before "home" like so:
<html>
<head>
<script>
// manually sets the <base> tag's href attribute so the app can be located in places other than root
var split = location.pathname.split('/');
var base = "";
for (var i = 0; i < split.length - 1; i++) {
base += split[i];
if (i < split.length - 2) {
base += "/";
}
}
window['_app_base'] = base;
document.write("<base href='" + base + "' />");
</script>
....
So far example, if the user loaded the home page at localhost:9000/hello/home, then the <base>
tag would look like this:
<base href='/hello' />
That code also sets a variable to this same value, which I then use in my app.module.ts to provide a new base value there as well:
import { APP_BASE_HREF } from '@angular/common';
@NgModule({
declarations: [...],
imports: [...],
providers: [
...,
{ provide: APP_BASE_HREF, useValue: window['_app_base'] || '/' }
]
});
However despite all this, the app is still looking for assets in the assets folder, which it thinks is still in the root location.
GET http://localhost:9000/assets/ionic-styles.css net::ERR_ABORTED
GET http://localhost:9000/inline.bundle.js net::ERR_ABORTED
GET http://localhost:9000/assets/font-awesome-4.6.3/css/font-awesome.min.css net::ERR_ABORTED
GET http://localhost:9000/assets/bootstrap.min.css net::ERR_ABORTED
GET http://localhost:9000/assets/global-styles.css net::ERR_ABORTED
GET http://localhost:9000/polyfills.bundle.js net::ERR_ABORTED
GET http://localhost:9000/styles.bundle.js net::ERR_ABORTED
GET http://localhost:9000/vendor.bundle.js net::ERR_ABORTED
What am I missing? I've also seen people take an approach where they specify a path in their ng build command... is that necessary on top of everything above? I'd really like to avoid having to make a separate build for everyone install, but if that's what it takes, please let me know.
Thanks.
UPDATE:
After a frustrating few days, my app is working using the code shown in the question above. It turns out I only needed to have the <script>
in my <head>
to modify the <base>
. There was no need to add the APP_BASE_HREF in the ngModule providers. However, adding the APP_BASE_HREF doesn't break anything either...
This is one of those problems where it "just worked" after dropping the problem for a week and coming back to it. Maybe there was some kind of cache issue going on? After all, I had tried updating the <base>
last week, but it was still looking in the wrong place for the assets. Though I had cleared the browser cache multiple times last week as I tried to debug this issue, so I'm not sure if cache was actually the problem.
I'm sorry this answer isn't going to be helpful for people who face this issue in the future. I really have no idea what fixed the issue. My best guess is that one of the answers below will likely point you in the right direction. It seems like no matter what I tried, it wasn't working for some unknown reason.
If you're facing this problem and have a specific question, feel free to message me or leave a comment, and I'll tell you how I have things set up.
assets/global-styles.css
, not/assets/global-styles.css
. – Glow