Skip to content

How to get Spring Boot to serve the Angular Router Paths

Published: at 06:22 PM (2 min read)

I was having a real issue with 404 white pages being served by the Spring Boot application for nested (/page/component) routes until I found this fix.

Table of contents

Open Table of contents

The Problem

I have a Spring Boot application that is serving my Angular front end, and this works great if you go to the root url (something like https://smale.codes) and even works as you navigate around the app. It all falls apart when you try to load a child page or refresh a child page (like https://smale.codes/module/component).

I had found a fix for a single child route, so you could go directly to https://smale.codes/module using the suggested mapping in this article from Spring, but this didn’t work for the next level.

The Fix

After some further reading I found the following, that can be put in the main class and allows the Spring Boot application to send any routes it is not configured to handle to the Angular application.

@SpringBootApplication
@ConfigurationPropertiesScan
@Controller // make it a Controller
public class LearningApplication {

 public static void main(String[] args) {
  SpringApplication.run(LearningApplication.class, args);
 }

  /**
   * This is the magic that will forward all unknown routes to the Angular app.
  */
 @GetMapping("/**/{path:[^\\.]*}")
 public String redirectApi() {
  return "forward:/";
 }
}

To prevent the app from failing to start due to the parser used for the mappings (it doesn’t like the starting /**), you need to add the below to your application.yaml file.

spring:
  mvc:
    pathMatch:
      matching-strategy: ANT_PATH_MATCHER

From here, you can have a sink route (**) in the Angular router to handle the 404.

Next

As a API usually has a prefix (/api,/rest or something) it would be good to tell Spring Boot that anything that isn’t matched and has that as a start should send a 404 response from the backend.

We can add the following to be sink for anything that starts with /api that is not handled by Spring.

@RequestMapping(value = "/{_:^api$}/**")
public String send404() {
  throw new NotFoundException();
}

If you have a few paths you want to match you can add a pipe and the next word. Below I have added test. This issue helped to get the right syntax.

 @RequestMapping(value = "/{_:^test|api$}/**")
 public String send404() {
  throw new NotFoundException();
 }

Resources

Part of the fix The other side of the fix The Starting point - GitHub issue The Starting point - GitHub Repo