If you’re tired of trying to solve this problem by following so many conflicting solutions – look here!!
After hours upon hours trying to follow all the scattered advice from dozens of stack overflow and blog posts, I’ve finally found the minimum PURE spring boot + angular 6 application to always redirect to index.html after a refresh on a non-root page WHILE maintaining all your REST API
endpoint paths. No @EnableWebMvc
, no @ControllerAdvice
, no changes to application.properties
, no custom ResourceHandlerRegistry
modifications, just simplicity:
Very important pre-requisite
You *must* include the output of ng build
into Spring’s resources/static
folder. You can accomplish this via the maven-resources-plugin
. Learn here: Copying multiple resource directories to independent target directories with maven
Code
@Controller
@SpringBootApplication
public class MyApp implements ErrorController {
public static void main(String[] args) {
SpringApplication.run(MyApp.class, args);
}
private static final String PATH = "/error";
@RequestMapping(value = PATH)
public String error() {
return "forward:/index.html";
}
@Override
public String getErrorPath() {
return PATH;
}
}
Reasoning
- Including the output of ng-build into
resources/static
at build time allows spring view redirects ("forward:/index.html"
) to succeed. It seems spring cannot redirect to anything outside of the resources folder so if you’re trying to access pages at the root of the site, it won’t work. - With default functionality (i.e. no additions of
@EnableWebMvc
or changes toapplication.properties
) navigating to/
automatically serves the index.html (iff it was included in theresources/static
folder) so no need to make changes there. - With default functionality (as stated above), any error encountered in a spring boot app routes to
/error
and implementingErrorController
overrides that behavior to – you guessed it – route toindex.html
which allowsAngular
to take over the routing.
Remarks
- Don’t settle for the
HashLocationStrategy
to get over this problem as it is not recommended by Angular: https://angular.io/guide/router#which-strategy-is-best