Software Engineer & Web Developer

Server-Side Rendering with Spring Boot and React

Step-by-Step Guide

In this guide, we'll integrate server-side rendering (SSR) of React components in a Spring Boot application using GraalVM.

1. Set Up Your Spring Boot Application

Ensure you have a Spring Boot application set up. You can create one using Spring Initializr or your preferred method.

spring init --dependencies=web my-springboot-react-ssr
cd my-springboot-react-ssr

2. Add Dependencies to pom.xml

Add the GraalVM JavaScript dependency to your pom.xml file:

<dependency>
    <groupId>org.graalvm.js</groupId>
    <artifactId>js</artifactId>
    <version>21.1.0</version>
</dependency>

3. Create Your React Application and Bundle It

Create your React application using Create React App or similar:

npx create-react-app my-react-app
cd my-react-app
npm run build

This creates a production build of your React application in the build directory.

4. Configure Spring Boot to Use GraalVM

Create a service in your Spring Boot application to render React components:

package com.example.ssr;

import org.graalvm.polyglot.Context;
import org.graalvm.polyglot.Value;
import org.springframework.stereotype.Service;

import java.nio.file.Files;
import java.nio.file.Paths;

@Service
public class ReactRenderer {

    private static final String REACT_COMPONENT_PATH = "path/to/your/build/static/js/main.js";

    public String renderComponent(String componentName, String propsJson) throws Exception {
        String jsCode = new String(Files.readAllBytes(Paths.get(REACT_COMPONENT_PATH)));

        try (Context context = Context.create("js")) {
            context.eval("js", jsCode);

            Value renderFunction = context.getBindings("js").getMember("renderComponent");
            if (renderFunction == null || !renderFunction.canExecute()) {
                throw new IllegalStateException("Render function not found or not executable");
            }

            Value result = renderFunction.execute(componentName, propsJson);
            return result.asString();
        }
    }
}

Ensure your React build exports a renderComponent function that takes the component name and props JSON.

5. Create a Controller to Render React Components

package com.example.ssr;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class SsrController {

    @Autowired
    private ReactRenderer reactRenderer;

    @GetMapping("/render")
    public String render(@RequestParam String component, @RequestParam String props) {
        try {
            return reactRenderer.renderComponent(component, props);
        } catch (Exception e) {
            e.printStackTrace();
            return "Error rendering component: " + e.getMessage();
        }
    }
}

6. Configure Your React Application for SSR

Ensure your React application exports the renderComponent function. In src/index.js:

import React from 'react';
import ReactDOMServer from 'react-dom/server';
import App from './App';

// Function to render a React component on the server
export function renderComponent(componentName, propsJson) {
    const props = JSON.parse(propsJson);
    let Component;
    switch (componentName) {
        case 'App':
            Component = App;
            break;
        // Add more components here
        default:
            throw new Error(`Unknown component: ${componentName}`);
    }
    return ReactDOMServer.renderToString(<Component {...props} />);
}

7. Build Your React Application

Rebuild your React application after modifying src/index.js:

npm run build

Now, your Spring Boot application should be able to render React components on the server using the /render endpoint.

Summary

By following these steps, you integrate server-side rendering of React components in a Spring Boot application using GraalVM. This setup helps improve the performance and SEO of your web application. Ensure to handle any potential errors and edge cases for a robust implementation.

Add your comment