Reputation: 709
I use Angular as frontend technology, spring boot for the backend and Azure Ingress as webserver. My problem is that when the user refreshes the site there comes an 404 error because of Angular routes. I wonder if this approach to solve this problem is a good practice and if there may araise any problem with my own AJAX calls:
@Configuration
class WebApplicationConfig
{
@Bean
public EmbeddedServletContainerCustomizer containerCustomizer()
{
return container -> {
container.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/index.html"));
};
}
}
?
What I am searching for is some kind of URL rewriting (e.g. on Apache webserver) for my technology stack. Currently there is a static folder in the JAR file that is returning my Angular files. If the link is requested always the angular files (index.html and dependencies) are returned but while the user is working the URL changes (only in frontend) and if he then hit site refresh there comes an 404 error.
e.g.
http://somehost/some/static/url/ <-- OK
http://somehost/some/static/url/and/angular/route <-- 404
So I wonder if the solution above would be a good one. Or maybe there is another better solution?
Upvotes: 0
Views: 340
Reputation: 386
It sounds like your Angular app is directly served by your Spring Boot app. If you want to stick with this solution (avoiding a separate web server) you will have to make sure that Spring Boot serves the index.html
of your Angular app under any route (except those intended for API of course), as stated by Mixalloff.
Here is how I did it in a project:
src/main/frontend
. So if you build the Angular app you will get its static resources in the folder src/main/frontend/dist
.maven-resources-plugin
to copy only the index.html
generated in src/main/frontend/dist
to the output directory target/classes/templates
. So there should be the file target/classes/templates/index.html
in the end.maven-resources-plugin
to copy any other static resources (like JavaScript, CSS, etc.) from src/main/frontend/dist
to the output directory target/classes/static
. This is where your files are also located currently.spring-boot-starter-mustache
to get Mustache auto-configured as your template engine for Spring MVC. We will use the index.html
generated for your Angular app as a Mustache template.Create a Spring controller with a method returning the index
view name for any path. Note the request mapping to /**
here:
@Controller
public class IndexPageController {
@RequestMapping("/**")
public String index() {
return "index";
}
}
The wildcard method returning the index page is automatically sorted last by Spring MVC, see https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#mvc-ann-requestmapping-pattern-comparison
So you can still add more controllers mapped to more specific paths, e.g. /api/v1/whatever
.
In the end, your Spring Boot app will always return the index.html
file for any route that does not match a more specific request mapping.
And this comes with even more sugar: Since the index.html
is processed as a Mustache template it can contain server-side template markup if needed.
Upvotes: 2
Reputation: 837
The Angular is independently determine routes and must manage the display of 404 Page and another pages. You need always give away index.html file for all requests in your server
Upvotes: 0