Angular only runs on port 4200 if you serve it with the angular-cli using ng serve.
You have to point your angular middleware.json files option to your dist directory of your angular2 app or copy your dist directory contents into your loopback "client" folder.
So it will look something like this :
middleware.json
.
.
"files": {
"loopback#static": {
"params": "$!../client/"
}
}
.
.
The dist directory is where angular outputs your files when you run
ng build
Make sure you don't have a router.js file in your loopback boot folder. This usually holds some route code to redirect the root url to a status output of your api, thus / will take you to your api status instead of your angular app's index.html.
Loopback serves the angular app, however, when you try to access the links directly, e.g. /blog/:id in other words something like /blog/f24382f3y23f9832 then it will fail because loopback does not know how to handle those links and even though loopback client points to angular, angular has not yet "bootstrapped" when querying those links directly.
To fix this, you will have to add custom middleware to redirect loopback to your angular index so that angular's router can take it from there.
So in your middleware.json file, change the following :
"final": {
"./middleware/custom404": {}
}
Then add a file custom404.js inside /server/middleware/ so that the full path is /server/middleware/custom404.js . If the middleware directory does not exist, create it.
Then inside the custom404.js file :
'use strict';
module.exports = function () {
var path = require('path');
return function urlNotFound(req, res, next) {
let angular_index = path.resolve('client/index.html');
res.sendFile(angular_index, function (err) {
if (err) {
console.error(err);
res.status(err.status).end();
}
});
};
};
This will redirect back to your angular app and angular's router will route the url correctly while still being served by loopback.
I use path.resolve
so that the link is first resolved according to our web path and not the current directory, else it will be considered as a malicious call and you will receive 403 errors.
I have read the angular.io docs and this is the correct way to implement this. See here angular.io docs . Read the part that is titled "Routed apps must fallback to index.html"
I have made a post of my own here Rewrite requests from loopback to angular2 (Refused to execute script because its MIME type ('text/html') is not executable) where I had a similar problem.