Spring Boot
Tomcat Server
HTML5 Mode
Web Development
Configuration

Spring boot Configure your tomcat server to work with html5Mode

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

When a single-page application uses HTML5 history mode, the browser URL no longer contains a hash fragment. That improves the URL shape, but it also means a direct refresh on /users/42 sends a real HTTP request to the server. If Tomcat and Spring Boot do not know how to handle that path, the user gets a 404 instead of your frontend app. The fix is to serve index.html for frontend routes while still letting real API and static asset requests behave normally.

Why Refreshing Breaks

Client-side routers in Angular, React, Vue, and similar frameworks can interpret /dashboard/settings once the SPA is already loaded. But when the browser reloads that URL, the server sees only an incoming HTTP request for /dashboard/settings.

If your backend has no controller for that path, Spring returns 404. HTML5 mode therefore requires a fallback route on the server side.

Put the SPA Assets in Spring Boot's Static Locations

Spring Boot serves static files automatically from locations such as src/main/resources/static. A typical setup looks like:

text
src/main/resources/static/index.html
src/main/resources/static/assets/app.js
src/main/resources/static/assets/app.css

With that in place, requests for /assets/app.js are served directly, while index.html can act as the shell for your SPA.

Forward Unknown Frontend Routes to index.html

A common Spring MVC solution is to forward non-API paths back to the SPA entry point.

java
1import org.springframework.stereotype.Controller;
2import org.springframework.web.bind.annotation.GetMapping;
3
4@Controller
5public class SpaForwardController {
6
7    @GetMapping(value = {
8        "/{path:[^.]*}",
9        "/**/{path:[^.]*}"
10    })
11    public String forward() {
12        return "forward:/index.html";
13    }
14}

This pattern works because:

  • it catches routes without a file extension
  • it avoids intercepting static files such as .js, .css, and .png
  • it forwards browser navigation paths back to index.html

Your frontend router then takes over from there.

Keep API Routes Separate

Do not forward everything blindly. Your backend API routes such as /api/users should still be handled by controllers or return proper API errors.

A common project structure is:

  • frontend routes under paths such as /app, /dashboard, or root-level SPA pages
  • backend routes under /api/**

Example REST controller:

java
1import org.springframework.web.bind.annotation.GetMapping;
2import org.springframework.web.bind.annotation.RestController;
3
4@RestController
5public class UserController {
6
7    @GetMapping("/api/users")
8    public String users() {
9        return "[]";
10    }
11}

As long as your SPA forwarding logic avoids /api/**, the frontend and backend can coexist cleanly.

Alternative With View Controllers

For a small application, you can also register view-controller forwards explicitly.

java
1import org.springframework.context.annotation.Configuration;
2import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
3import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
4
5@Configuration
6public class WebConfig implements WebMvcConfigurer {
7
8    @Override
9    public void addViewControllers(ViewControllerRegistry registry) {
10        registry.addViewController("/{spring:[^.]+}")
11                .setViewName("forward:/index.html");
12        registry.addViewController("/**/{spring:[^.]+}")
13                .setViewName("forward:/index.html");
14    }
15}

The same caveat applies: be careful not to swallow real backend endpoints.

Tomcat Is Not the Real Problem

Even though people often say "configure Tomcat for HTML5 mode," the real work is usually in your Spring MVC routing. Embedded Tomcat serves the application, but the fallback behavior is typically implemented in Spring.

If you deploy behind Nginx, Apache, or a cloud load balancer, that proxy layer may also need equivalent SPA fallback rules. The route must be handled correctly at the layer that sees the request first.

Common Pitfalls

The most common mistake is forwarding every unmatched request to index.html, including API calls. That hides real backend errors and makes debugging harder.

Another mistake is forgetting to exclude static assets. If /main.js gets forwarded to index.html, the browser fails to load the app correctly.

Developers also sometimes place the built SPA assets outside Spring Boot's static resource locations and then compensate with increasingly confusing route rules.

Finally, if a reverse proxy sits in front of Spring Boot, it may need matching fallback behavior. Fixing only the application layer may not be enough.

Summary

  • HTML5 mode requires the server to return index.html for frontend navigation routes.
  • Keep SPA assets in Spring Boot's static resource locations.
  • Forward unknown non-API, non-static routes to index.html.
  • Do not let the fallback hide real API endpoints or asset requests.
  • If a reverse proxy is in front, make sure it supports the same routing model.

Related reading
Course
Intermediate
27 lessons
14 hours
OOD Fundamentals

Master object-oriented design from first principles, SOLID, design patterns, and classic interview problems with hands-on coding.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.