The easiest way I get my SPAs to work with a Spring backend API is to have 2 different controllers: one for the root index page of the SPA and the other controller is used to manage various RESTful API endpoints:
Here are my two controllers:
MainController.java
@Controller
public class MainController {
@RequestMapping(value = "/")
public String index() {
return "index";
}
}
MonitoringController.java
@RestController
@RequestMapping(value = "api")
public class MonitoringEndpoints {
@GetMapping(path = "/health", produces = "application/hal+json")
public ResponseEntity<?> checkHealth() throws Exception {
HealthBean healthBean = new HealthBean();
healthBean.setStatus("UP");
return ResponseEntity.ok(healthBean);
}
}
Notice how the API endpoint controller utilizes the '@RestConroller' annotation while the main controller utilizes the '@Conroller' annotation. This is because of how Thymeleaf utilizes it's ViewResolver. See:
Spring Boot MVC, not returning my view
Now go ahead and place your index.html page at src/main/resources/templates/index.html because Spring by default looks for your html pages within this location.
My index.html pages looks like this:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head lang="en">
<meta charset="UTF-8"/>
<title>EDP Monitoring Tool</title>
</head>
<body>
<!-- Entry point to our ReactJS single page web application -->
<div id="root"></div>
<script type="text/javascript" src="built/bundle.js"></script>
</body>
</html>
Not sure how you're wiring up your frontend, whether that is a ReactJS app or something but I believe this information would be helpful for you. Let me know if I can answer additional questions for you.
In addition, if you're using Webpack, you can set up the entry point of your JS files via the webpack.config.js file under the entry key so like so:
entry: ['./src/main/js/index.js']
static/
directory (you can use maven frontend plugin to automate that). Then Spring Boot will serve them as static files, you don't need to worry about redirecting to html or js. Are you using hash-based URL in your SPA (so.com/#/route/...)? If so you have nothing more to do in Spring – Frieda