How to handle deep links in Angular?
This was tripping me up for a while too. But just for the record, the Angular deployment documentation has a good section about this which you can find here https://angular.io/guide/deployment#server-configuration
The bottom line is that if you navigate from outside your app to a location in your app (other than the root location "/") the browser sends a GET request to the server asking for the full URL. But since that URL is meant to be interpreted as a route in your front-end app and not as a resource in your back-end server the server will throw a 404 (unless you happen to have also set up your server as a static file server and there happens to be a resource at that location). So what you need to do is configure your server to respond with the front-end app assets instead of returning a 404, that way when the front-end app loads in the browser it can check the URL and engage it's routing logic.
I experienced the same difficulties to get NGINX 1.17 to work in combination with routing in Angular 9. I finally found an NGINX configuration that supports deep linking respectively routing and at the same time doesn't require the usage of Angular's HashLocationStrategy
nor setting <base href="">
.
The key difference that I made is that I added the root
directive to the location
block to specify the root directory that will be used to search for a file:
events {
worker_connections 1024;
}
http {
server {
listen 80;
location / {
root /usr/share/nginx/html;
try_files $uri $uri/ /index.html;
}
}
include /etc/nginx/mime.types;
}
This NGINX configuration assumes that the content of Angular's dist folder resides in /usr/share/nginx/html/
. With this configuration I don't experience any HTTP 404 errors for routes like /someroute/123456
(even when I reload the page in the browser by hitting F5 or when I navigate to this route directly).
It sounds like you may be missing the <base href="">
tag. This tag tells the Angular router what the base URI is for your application. If this is not present then Angular assumes that the initial navigation URI (in your case, /whatever/someroute/123456
) is the base URI and all subsequent routing will be performed relative to that URI.
Try including <base href="/whatever/">
in the <head>
element of your index.html
to direct the router accordingly.
You may also control the <base href="">
meta tag via ng build
if you are using the Angular CLI:
ng build --base-href '/whatever/'
You can switch to the HashLocationStrategy, i.e.
RouterModule.forRoot(appRoutes, {useHash: true});
This results in all app urls being index.html, followed by "#" and then the routing information.
Since you're always going to index.html, regardless of the route, you won't get a 404 for any valid URL.