I am trying to get rid ot #
-red URLs in my Angular app (Google recommends it in the case that your app does not present indexable content on the first load). The web application is in the static/
directory of my Spring Boot application.
So I disabled the use of #
:
export const AppRouting = RouterModule.forRoot(routes, {
useHash: false,
enableTracing: false
});
On my local machine evereything works fine e.g.
lists all cars in Berlin but
Gives me HTTP 404 after deploying the site.
I'm not sure why this happens. How can I fix this?
However, the root URL http://example.com is working correctly. The content of the website is displayed but any page below cannot be reached.
This is what I ended up doing. It is simpler as the length of this answer might suggest.
I moved all my apps (there are two at the moment) to sub-directories. This means that all my apps are required to work under a base-href as in
www.example.com/admin-tool/index.html
www.example.com/web/index.html
This is the ng
command I am using to build the admin-tool
app:
#!/usr/bin/env bash
BASE_HREF=admin-tool
ng build --aot --prod --base-href /$BASE_HREF/ --output-hashing none --output-path dist/$BASE_HREF --deploy-url /$BASE_HREF/
Move/copy the content in dist/
(the output of the ng build
) to (in my case) src/main/resources/static
if you're not building it there already:
src/main/resources/static/admin-tool
src/main/resources/static/web
As mentioned in other answers one now has to forward requests to the respective index.html
"files" (let's just call it like that).
Here is why (as I understand it): Before we did all this, Angular just worked on #
-ed path which caused the JS code to do the updates based on what's after the #
. And if I'm getting it right - removing the #
will essentially mean that the browser is now making GET requests for all those URLs. So from the cars
example, if I have a place/route http://www.example.com/web/cars/berlin then this will now be a GET request which the server has to handle - in this case forward it to the correct endpoint.
Below is the code I am using in my backend to accomplish this:
@Controller
public class ForwardController {
@RequestMapping(value = "/*")
public String rectRoot(HttpServletRequest request) {
return "forward:/web/index.html";
}
@RequestMapping(value = "/**/{[path:[^\\.]*}")
public String redirect(HttpServletRequest request) {
if (request.getRequestURI().startsWith("/admin-tool")) {
return "forward:/admin-tool/index.html";
} else if (request.getRequestURI().startsWith("/web")) {
return "forward:/web/index.html";
}
return "forward:/web/index.html";
}
}
I don't give it a 100% yet, and I really hope this is just a workaround, but so far I am not having any issues with it.
Now here is why I am doing all this:
Apparently it's recommended to move away from #
-ed paths for several reasons. Since I am using Angular, I'll have to walk a few more miles in order to get search engine optimization (SEO) going but from what I get ([1], [2], [3]) you should avoid it since Google does not index it. They might only use it as an anchor but if you have AJAX content behind your #
you're going to have a bad time.
See further [4] about #!
which also seems to be deprecated by now and also take a look at [5] and [6].
[1] https://www.oho.com/blog/explained-60-seconds-hash-symbols-urls-and-seo
[2] https://www.seroundtable.com/google-no-hashtags-in-urls-26537.html
[3] https://www.seroundtable.com/google-no-url-fragments-23449.html
[4] https://webmasters.stackexchange.com/a/18606/64452
[5] https://webmasters.googleblog.com/2015/10/deprecating-our-ajax-crawling-scheme.html
[6] https://snipcart.com/blog/angular-seo-universal-server-side-rendering