I'm developing a spring backend for a react-based single page application where I'm using react-router for client-side routing.
Beside the index.html page the backend serves data on the path /api/**
.
In order to serve my index.html from src/main/resources/public/index.html
on the root path /
of my application I added a resource handler
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/").addResourceLocations("/index.html");
}
What I want to is to serve the index.html page whenever no other route matches, e.g. when I call a path other than /api
.
How do I configure such catch-all route in spring?
I use react and react-router in my spring boot app, and it was as easy as creating a controller that has mapping to
/
and subtrees of my website like/users/**
Here is my solutionApi calls aren't caught by this controller and resources are handled automatically.
Avoid @EnableWebMvc
By default Spring-Boot serves static content in
src/main/resources
:Take a look at this and this;
Or keep @EnableWebMvc and override addViewControllers
Did you specify
@EnableWebMvc
? Take a look a this: Java Spring Boot: How to map my app root (“/”) to index.html?Either you remove @EnableWebMvc, or you can re-define
addViewControllers
:Or define a Controller to catch
/
You may take a look a this spring-boot-reactjs sample project on github:
It does what you want using a Controller:
Its
index.html
is undersrc/main/resources/templates
To answer your specific question which involves serving up the Single Page App (SPA) in all cases except the /api route here is what I did to modify Petri's answer.
I have a template named polymer that contains the index.html for my SPA. So the challenge became let's forward all routes except /api and /public-api to that view.
In my WebMvcConfigurerAdapter I override addViewControllers and used the regular expression: ^((?!/api/|/public-api/).)*$
In your case you want the regular expression: ^((?!/api/).)*$
This results in being able to hit http://localhost or http://localhost/community to serve up my SPA and all of the rest calls that the SPA makes being successfully routed to http://localhost/api/posts, http://localhost/public-api/posts, etc.
Found an answer by looking at this question
Since my react app could use the root as forward target this ended up working for me
To be honest I have no idea why it has to be exactly in this specific format to avoid infinite forwarding loop.
I have a Polymer-based PWA hosted inside of my Spring Boot app, along with static web resources like images, and a REST API under "/api/...". I want the client-side app to handle the URL routing for the PWA. Here's what I use:
This should work for Angular and React apps as well.