Closed adamhpan closed 7 years ago
There are technically two applications in this repository. One is for the backend which serves to static content or HTML, and the Angular portion of the app is only on the front-end. So I deployed the backend to Heroku (https://angular2-login-seed.herokuapp.com/api/....), and the front-end app is just in the gh-pages branch of this repository. When you visit https://domfarolino.com/angular2-login-seed you're hitting the static front-end angular app, and whenever the angular app needs some data to display on the page it hits the API deployed on Heroku. This make sense?
The front and back end are completely divorced, so the deep linking/routing is all done with the Angular app in the front-end.
It is possible to deploy them all with one app, but it is messier. You'd need the backend application to serve the same HTML file for any route that does not start with /api/ so that the Angular router could actually handle each route itself (and not let the backend serve some nonesense), and furthermore you'd need to be serving the index from the dist/ folder that contains the compiled version of the angular app.
When creating a robust single page app in something like Angular it makes sense to let Angular (with all its features and glory etc) handle just about everything except for dynamic data collection, which is what the backend does in this application. So when you deploy to Heroku you should only be deploying the back-end app, now you can serve the front-end from anywhere and just make sure the Angular app hits the correct back-end.
Let me know if you need any more info/help
Totally, I get that we have the Angular app and api app.
I'm having trouble with the Angular app right now. I can't seem to use any of the deep links when I only host it. The app runs fine when it first get's hit but if I refresh, the page breaks.
Hmm, could you give me the URL you're hosting the Angular app at?
Here we are https://ng-login-seed.herokuapp.com/
Here are the reproduction steps
"scripts": {
"start": "http-server ./dist",
"preinstall": "npm install -g http-server",
"postinstall": "ng build --prod"
},
Expected - the login screen should display correctly Actual - there's a white screen
I haven't enabled cors so none of the api calls will work.
Thanks for the information. http-server
is a simple server in that it will serve you whatever files you're trying to get (denoted by URL). If it is anything like python -m SimpleHTTPServer
it probably doesn't do much more than this (path aliasing and other things with logic). It is a dumb server, in that if a file exists it will give it to you. So if you visit /
, the server will automatically look for a /index.html
which exists since Angular built it. However this kind of server typically does not support deep-linking. Think about it, on the front end we've changed the URL from / => /login
at some point, but we've never told the server about this. When the URL changed, Angular knew what to do and it changed the front-end content accordingly. The server however, only remembers our first request that it was able to handle successfully - /
.
Fast forward to us refreshing the page after the URL changed on the front-end. Now we're actually saying, "hey server - serve us up the content at /login
for us" since our URL has changed to /login
. The server, http-server
in this case will look for a /login
folder in the ./dist
folder in your case instead of serving up index.html
. Since it can't find it, it will fail (different servers will fail differently). So the key to supporting deep-linking with a server is to serve the same static HTML index.html
no matter what the route we request is. Why is this? Well because we've already seen that Angular knows how to deal with those links when they are given, we just need to make the server more like a sieve, so that it will always let Angular respond.
Regarding http-server, I've never used it so I don't know if there's a way to say "hey server, on request of /
, /login
, register
, /heroes
, ... serve the same index.html
page no matter what". This is something you'll need to find out. With express/Node.js it is very very simple to do this.
Does this make sense why the deep-linking is failing? It is nothing to do with the Angular app, it is instead a fundamental issue that very watered-down basic http servers have when trying to serve single-page applications with routers built in. The idea is typically we want to serve the same static content no matter what request is made, and sometimes baking those rules into the server is simple.
For example when I try to retrieve /login
when running the http-server locally in the ./dist
folder, I get the following error:
[Mon Nov 21 2016 17:02:24 GMT-0500 (EST)] "GET /login" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.100 Safari/537.36" [Mon Nov 21 2016 17:02:24 GMT-0500 (EST)] "GET /login" Error (404): "Not found"
Because we've got no rule telling the server to route everything to index.html
. Regarding your original issue with the nginx server that should've routed everything to index.html I'm not sure why that did not work. I would assume the server was not set up to route everything to index.html as you may have thought but I could be wrong
I'll try the nginx routing again.
Thanks for the help!
I can't get the deep links to work when I'm hosting the application on Heroku/EB. I've tried to run an nginx server to route everything to the index.html in ./dist but the deep links are still not found.
Can you run through how you hosted the project on Heroku?