Issue
I am working on Spring Boot and React.
I am exposing some REST APIs that will be consumed by the React app.
In React I have user route
Something like this
<Switch>
<Route exact path="/" component={Home}></Route>
<PrivateRoute path="/profile" authenticated={this.state.authenticated} currentUser={this.state.currentUser}
component={Profile}></PrivateRoute>
<Route path="/login"
render={(props) => <Login authenticated={this.state.authenticated} {...props} />}></Route>
<Route path="/signup"
render={(props) => <Signup authenticated={this.state.authenticated} {...props} />}></Route>
<Route path="/oauth2/redirect" component={OAuth2RedirectHandler}></Route>
<Route component={NotFound}></Route>
</Switch>
Endpoints:
http://localhost:3000/login
http://localhost:3000/signup
http://localhost:3000/dashboard
I have bundled both React and Spring Boot by adding these line in pom.xml
to run on a single port 8080
<plugin>
<groupId>com.github.eirslett</groupId>
<artifactId>frontend-maven-plugin</artifactId>
<version>1.6</version>
<configuration>
<workingDirectory>authserver-react</workingDirectory>
<installDirectory>target</installDirectory>
</configuration>
<executions>
<execution>
<id>install node and npm</id>
<goals>
<goal>install-node-and-npm</goal>
</goals>
<configuration>
<nodeVersion>v8.11.3</nodeVersion>
<npmVersion>5.6.0</npmVersion>
</configuration>
</execution>
<execution>
<id>npm install</id>
<goals>
<goal>npm</goal>
</goals>
<configuration>
<arguments>install</arguments>
</configuration>
</execution>
<execution>
<id>npm run build</id>
<goals>
<goal>npm</goal>
</goals>
<configuration>
<arguments>run build</arguments>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<phase>generate-resources</phase>
<configuration>
<target>
<copy todir="${project.build.directory}/classes/static">
<fileset dir="${project.basedir}/authserver-react/build" />
</copy>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
Once done I run build and mvn spring-boot:run
and open browser at http://localhost:8080
React comes in picture and redirect to http://localhost:8080/login
The problem is if I refresh the Page by clicking refresh button, Spring throws Whitelabel Error Page.
This is happening because I have not defined any Controller with "/login". But I don't want to define that.
Now I am not sure how do I differentiate React route with Spring APIs.
I don't want to run React in a different port and Spring Boot in a different port.
Solution
Well, finally I got it right. It was just a matter of understanding the flow.
antrun
is configured in pom.xml
to copy my react /build
files to Spring's /static
folder.
This means my react's index
file will we residing in the static folder.
I only had to write a controller which resolves my react routes to index.
Something like this
@Controller
public class TemplateFile
{
@RequestMapping(value={"/login", "/dashboard", "/signup" })
public String HomePage() {
return "index";
}
}
Now my code works fine with spring port i.e
http://localhost:8080/login
http://localhost:8080/signup
http://localhost:8080/dashboard
Note: I still need to optimize the controller class with some regex.
Answered By - MyTwoCents