Im trying to host a react app with a spring project on a tomEE server. I'm having some problems with the react routes on the server. It works fine locally when running the react app and sprint app, but only the root path (/) works on the server. There are no error messages in the server logs.
The 404 error seems to be coming from spring: 404 error message
This is the controller class:
@CrossOrigin
@RestController
@RequestMapping("api")
public class DemoController {
@GetMapping("/demo")
public List<String> demo(){
List<String> list = new ArrayList<>(Arrays.asList("Hello", "World", "from", "Spring!"));
return list;
}
}
The react App.js:
import {Route, Routes} from "react-router-dom";
import Test from "./components/test";
function App() {
return (
<Routes>
<Route index element={<Test />} />
<Route path="test" element={<div>Test</div>} />
</Routes>
);
}
export default App;
The index.js:
...
import {BrowserRouter} from "react-router-dom";
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<BrowserRouter basename={process.env.PUBLIC_URL}>
<App />
</BrowserRouter>
</React.StrictMode>
);
env.local:
PUBLIC_URL=.
env.production:
PUBLIC_URL=/Expo-project-0.0.1-SNAPSHOT
Scripts in package.json:
"scripts": {
"start": "react-scripts start",
"build": "env-cmd -f ./.env.production react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
}
pox.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.9</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>no.hvl.dat109</groupId>
<artifactId>Expo-project</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>Expo-prosject</name>
<description>Expo-prosject</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
I have tried adding a trailing slash in the .env files. Using hashroutes instead of browserroutes. Changing the controller to point at the index file. But we might have done something wrong here, because i think the problem is related to the routes not pointing to the index.html at all time.
I found a solution. As you said the 404 error is caused by spring and not react. You want all routes except /api to point to your react index.html file.
To solve this I created a new controller. In this case i called it Controller.java, and paste the code below.
@org.springframework.stereotype.Controller
public class Controller {
@RequestMapping(value = { "/", "/{x:[\\w\\-]+}", "/{x:^(?!api$).*$}/*/{y:[\\w\\-]+}","/error" })
public String index() {
return "index.html";
}
}
This code redirects all requests except /api to the index.html file using regex.