How to integrate React.js with Spring Boot

In this tutorial, I will show you step by step to integrate React.js with Spring Boot so that Spring Boot project can serve React App. You will also know how to configure React SPA Routing to avoid Whitelabel Error Page.

Related Posts:
React + Spring Boot + MySQL: CRUD example
React + Spring Boot + PostgreSQL: CRUD example
React + Spring Boot + MongoDB: CRUD example
Spring Boot + React: JWT Authentication with Spring Security
React File Upload/Download example with Spring Boot Rest Api

Serverless:
React Firebase CRUD with Realtime Database
React Firestore CRUD App example | Firebase Cloud Firestore


React.js & Spring Boot application Overview

Assume that we have 2 projects: React & Spring Boot:

integrate-reactjs-spring-boot-project-structure

For example, if we run them separately:

  • Spring Boot Server exports Rest Apis at Url: http://localhost:8080/
  • React.js Client runs at url: http://localhost:8081/

Using React to call Spring Rest API:

integrate-reactjs-spring-boot-separated-port

Otherwise, when deploying React production-build with Spring Boot project, we only need to run Spring Boot Project for the fullstack (React.js + Spring Boot) system.

In this example, we access http://localhost:8080/.

integrate-reactjs-spring-boot-same-server

Technology Stack

  • Node.js
  • React 16
  • React Router
  • React Scripts 3
  • Spring Boot 2
  • Spring Tool Suite
  • Maven 3.6.1

Setup React Client

You can use your own React Project, or just download the source code on Github, or follow these steps to create a new one.

Open cmd and create a new React Project as following command:

npx create-react-app react-crud

After the process is done. We create additional folders and files like the following tree:


public

src

components

add-tutorial.component.js

tutorial.component.js

tutorials-list.component.js

services

tutorial.service.js

App.css

App.js

index.js

package.json


Because I want to keep this tutorial simple and brief, please continue to develop this App with instruction in the post:
React.js CRUD example to consume Web API

Import React Project to Spring Tool Suite

Open Spring Tool Suite, right click on Package Explorer and choose Import -> General -> Projects from Folder or Archieve, press Next.

Find the React Project that we’ve just created above and press Finish, react-crud is imported like this:

integrate-reactjs-spring-boot-import-client-project

To clean the source code in STS, we need to remove node_modules folder by following the steps:

  • Right click on react-crud project, choose Properties, then Resource -> Resource Filter.
  • Press Add Filter…, choose Filter Type: Exclude all, Applies to: Files and folders, and check All children (recursive), with ‘File and Folder Atributes’, we specify node_modules:
  • integrate-reactjs-spring-boot-node-modules

Press OK, then Apply, the result will be like this:

integrate-reactjs-spring-boot-exclude-node-modules

Setup Spring Boot Server

You can use your own Spring Boot Project, or just download the source code on Github, or follow these steps to create a new one.

Use Spring web tool or your development tool (Spring Tool Suite, Eclipse, Intellij) to create a Spring Boot project.

Then open pom.xml and add these 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>mysql</groupId>
	<artifactId>mysql-connector-java</artifactId>
	<scope>runtime</scope>
</dependency>

The instruction can be found in the post:
Spring Boot, Spring Data JPA – Rest CRUD API example

Now we have 2 projects together in Spring Tool Suite:

integrate-reactjs-spring-boot-together

Let’s continue to the most important part.

Integrate React.js with Spring Boot

Build React App

Currently React Client and Express server work independently on ports 8081 and 8080.

The first thing we need to do is to build React App for production.

Run command:
npm run build
– or yarn build

PS ...\react-crud> npm run build

> react-crud@0.1.0 build D:\Projects\ReactProjects\react-crud
> react-scripts build

Creating an optimized production build...
Browserslist: caniuse-lite is outdated. Please run the following command: `yarn upgrade`
Compiled successfully.

File sizes after gzip:

  52.63 KB  build\static\js\2.8091b331.chunk.js
  22.44 KB  build\static\css\2.47e06e2e.chunk.css
  2.38 KB   build\static\js\main.2cd554a3.chunk.js
  774 B     build\static\js\runtime-main.efee8004.js
  144 B     build\static\css\main.9c6cdb86.chunk.css

The project was built assuming it is hosted at /.
You can control this with the homepage field in your package.json.

The build folder is ready to be deployed.
You may serve it with a static server:

  yarn global add serve
  serve -s build

Find out more about deployment here:

  bit.ly/CRA-deploy

Now you can see new build folder with content as following:

integrate-reactjs-spring-boot-build-production

Integrate React production into Spring Boot Project

Now we need to copy all files from React build folder to src/target/classes/static folder of Spring Boot project.

There are 2 way to do this:

  1. Manually copy/paste
  2. Using maven-resources-plugin

Open pom.xml, add following plugin:

<build>
  <plugins>
    <plugin>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-maven-plugin</artifactId>
    </plugin>

    <plugin>
      <artifactId>maven-resources-plugin</artifactId>
      <executions>
        <execution>
          <id>copy-resources</id>
          <phase>validate</phase>
          <goals>
            <goal>copy-resources</goal>
          </goals>
          <configuration>
            <outputDirectory>${basedir}/target/classes/static/</outputDirectory>
            <resources>
              <resource>
                <directory>${basedir}/../react-crud/build</directory>
              </resource>
            </resources>
          </configuration>
        </execution>
      </executions>
    </plugin>
  </plugins>
</build>

In the code above, we specify outputDirectory for the destination folder, and resource>directory for the source folder.

Serve React App on Spring Boot

Build and run the Spring Boot server with commands:
mvn clean install
mvn spring-boot:run

Open browser with url: http://localhost:8080/.
The result:

integrate-reactjs-spring-boot-run-demo

Spring Boot + React: Whitelabel Error Page

Oh yeah! Everything looks good.
But wait, let’s try to refresh the page.
What happened?

integrate-reactjs-spring-boot-white-label-error

To handle this error, we’re gonna enable hash(#) in React App Routing by using HashRouter.
It will keep the UI route in hash part of the URL, which should not make the server return 404.

So, in React Project, let’s open index.js file and change BrowserRouter into HashRouter.

import React from "react";
import ReactDOM from "react-dom";
import { HashRouter } from "react-router-dom";

import App from "./App";
import * as serviceWorker from "./serviceWorker";

ReactDOM.render(
  <HashRouter>
    <App />
  </HashRouter>,
  document.getElementById("root")
);

serviceWorker.unregister();

Don’t forget to rebuild the React App and copy all files and folders in build directory (React project) into target/classes/static folder (Spring Boot project).

Now Our Url is hashed(#) after port number: http://localhost:8080/#/tutorials

integrate-reactjs-spring-boot-same-server

Now you can refresh the page without worrying about Whitelabel Error.

Conclusion

Today we’ve learned how to integrate React.js with Spring Boot Application. We also handle “Whitelabel Error Page” case for Spring Boot + React Project. Now you can use Spring Boot to serve React App easily.

There are many fullstack Spring Boot + React examples that you can apply this approach to integrate:
React + Spring Boot + MySQL: CRUD example
React + Spring Boot + PostgreSQL: CRUD example
React + Spring Boot + MongoDB: CRUD example
Spring Boot + React: JWT Authentication with Spring Security
React File Upload/Download example with Spring Boot Rest Api

Or Serverless:
React Firebase CRUD with Realtime Database
React Firestore CRUD App example | Firebase Cloud Firestore

Further Reading

Source Code

You can find the complete source code for this tutorial at Github.

Leave a Reply

Your email address will not be published. Required fields are marked *