Let's get started with a Microservice Architecture with Spring Cloud:
Configure Spring Boot to Redirect 404 to a Single Page Application
Last updated: March 31, 2026
1. Introduction
Single-page applications (SPAs) such as those built with React, Angular, or Vue often rely on client-side routing. When served from a Spring Boot backend, refreshing the page or accessing a wrong link sends a request for a non-existent server path. Spring Boot then returns a 404 error.
To make the SPA work correctly, we need to forward all unmatched requests to index.html with HTTP status 200. This lets the frontend router handle the path.
In this tutorial, we’ll learn how to configure Spring Boot so that all unknown routes are redirected to the SPA’s index.html.
2. Maven Dependency
Let’s start by importing the spring-boot-starter-web dependency to our pom.xml:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>3.3.2</version>
</dependency>
3. Setting Up a Basic SPA with Spring Boot
Let’s consider an SPA deployed with Spring Boot, where the compiled frontend files are placed inside the resources directory:
src/main/resources/static
For example, a minimal index.html could look like:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Baeldung</title>
</head>
<body>
<h1>Home Page</h1>
</body>
</html>
Next, we create a simple controller to forward the root path:
@Controller
public class HomeController {
@RequestMapping("/")
public String getHome(){
return "forward:/index.html";
}
}
When a user accesses the root path http://localhost:8080/, Spring Boot serves index.html correctly.
However, if the user refreshes a client-side route like http://localhost:8080/dashboard, Spring Boot tries to find a server mapping for /dashboard and returns 404 Not Found. Instead, we want Spring Boot to return index.html so the SPA router can handle the route.
4. Redirecting 404 Not Found Errors
In this section, we describe some solutions for redirecting unmatched requests to index.html.
4.1. Using a Controller to Forward Unknown Routes
Let’s create a controller that forwards all unmapped paths to index.html:
@Controller
public class SpaForwardController {
@RequestMapping(value = "/{path:[^\\.]*}")
public String redirect() {
return "forward:/";
}
}
The unmatched requests without a file extension are forwarded to “/”, which returns index.html.
If a specific mapping exists (for example, @GetMapping(“/dashboard”)), Spring selects it with higher precedence, and the catch-all pattern is ignored. For any other path without a matching handler (such as /settings), the request falls through to the catch-all mapping and gets forwarded to index.html.
Also, we need to support deeper routes like /dashboard/settings. To do this, we can expand the controller mapping:
@Controller
public class SpaForwardController {
@RequestMapping(value = {
"/{path:[^\\.]*}",
"/{path:[^\\.]*}/**/{subpath:[^\\.]*}"
})
public String redirect() {
return "forward:/";
}
}
4.2. Using a Custom Error Controller
Another approach is to intercept 404 errors and redirect them to the SPA entry point:
@Controller
public class SpaErrorController implements ErrorController {
@RequestMapping("/error")
public String handleError() {
return "forward:/index.html";
}
}
This method ensures that any unknown route eventually loads the SPA.
However, this approach may also intercept real backend 404 errors, which may not always be desirable.
4.3. Using WebMvcConfigurer
Another approach is to centralize error handling and avoid the need to explicitly match route patterns.
We can achieve this by implementing the WebMvcConfigurer interface and registering a custom error page:
@Configuration
public class WebApplicationConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/notFound")
.setViewName("forward:/index.html");
}
@Bean
public WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> containerCustomizer() {
return container -> {
container.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/notFound"));
};
}
}
In this configuration, any request that results in a 404 Not Found error is redirected to /notFound. This endpoint then forwards the request to index.html.
However, it also means that all 404 errors—including those from backend APIs—are redirected to the SPA, which may not always be desirable.
5. Test
After starting the Spring Boot application, we can verify the configuration by accessing different URLs.
First, we request the root path:
$ curl -i http://localhost:8080/
The response returns 200 along with the contents of index.html:
HTTP/1.1 200
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Baeldung</title>
</head>
<body>
<h1>Home Page</h1>
</body>
</html>
Next, we simulate accessing a client-side route:
$ curl -i http://localhost:8080/dashboard
Instead of returning a 404 Not Found, the application responds with 200 and serves index.html. This confirms that the request is forwarded and handled by the SPA router.
6. Conclusion
In this article, we explored how to forward unknown routes to index.html when serving a single-page application with Spring Boot. We examined multiple approaches, including using a custom controller, configuring WebMvcConfigurer, and handling errors via a custom error mapping.
As always, the source code is available over on GitHub.
















