Software Engineer & Web Developer

Advanced SSR and SSG with Spring Boot & React

Advanced Server-Side Rendering and SSG with Spring Boot & React

Your previous blog post covering SSR with Spring Boot and React gained a lot of attention. This follow-up goes deeper—covering advanced techniques like Static Site Generation (SSG), React hydration strategies, CDN optimization, and DevOps deployment flows.

1. SSR vs. SSG: What's the Difference?

SSR (Server-Side Rendering) means rendering React components on the server at runtime. SSG (Static Site Generation) pre-renders pages at build time. Both help with:

  • SEO improvement (bots get HTML)
  • Faster first paint (TTFB optimized)
  • Better perceived performance

SSG is best for static content. SSR is ideal when data must be fetched at request time.

2. Review: SSR with Spring Boot + Thymeleaf

Your original article explained how to use Thymeleaf for SSR inside a Spring Boot controller:

// Controller
@GetMapping("/")
public String index(Model model) {
  model.addAttribute("data", myService.getData());
  return "index"; // loads index.html
}

This works well, but mixing server and React logic can become inflexible. Let’s explore alternatives.

3. Option A: Full SSR using Express + React + Spring API

Let Spring Boot serve the API, and let an Express server render the React app on the server:

3.1 Express SSR Setup

// server.js
import express from 'express';
import React from 'react';
import { renderToString } from 'react-dom/server';
import App from './App';
import fs from 'fs';
import path from 'path';

const app = express();

app.use(express.static('build'));

app.get('*', (req, res) => {
  const appHtml = renderToString(<App />);
  const indexHtml = fs.readFileSync(path.resolve('./build/index.html'), 'utf8');
  const finalHtml = indexHtml.replace('<div id="root"></div>', `<div id="root">${appHtml}</div>`);
  res.send(finalHtml);
});

app.listen(3000);

3.2 Benefits

  • Decouples rendering from Java stack
  • Allows fine-grained control over React hydration
  • Frontend stays pure React

4. Option B: Static Site Generation (SSG)

Use tools like react-snap or vite-plugin-ssg to prerender your pages at build time.

npx react-snap
// Or with Vite
npm i vite-plugin-ssg

Generated HTML pages can be served by Spring Boot from /static folder or any CDN.

5. React Hydration Strategies

Hydration reactivates the React app on the client after SSR. To optimize this:

  • Use react-lazy-hydration or react-hydrate-on-visiblity
  • Split large components using React.lazy() and Suspense
  • Only hydrate visible sections ("Islands architecture")
import { lazyHydrate } from 'react-lazy-hydration';

lazyHydrate(() => import('./HeavyComponent'), { whenVisible: true });

6. Caching and CDN Strategy

  • Use Spring’s WebMvcConfigurer to add caching headers
  • Host static HTML/JS on Cloudflare or AWS CloudFront
@Configuration
public class CacheConfig implements WebMvcConfigurer {
  public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry.addResourceHandler("/static/**")
      .addResourceLocations("classpath:/static/")
      .setCachePeriod(31556926); // 1 year
  }
}

7. SEO Improvements

  • Inject meta tags server-side using react-helmet
  • Add Open Graph tags, Twitter cards, and JSON-LD

8. Docker and CI/CD Deployment

Create a multi-stage Dockerfile that builds both Java and Node apps:

# Dockerfile
FROM node:18 as frontend
WORKDIR /app
COPY client/ .
RUN npm install && npm run build

FROM maven:3.8-jdk-17 as backend
WORKDIR /app
COPY server/ .
RUN mvn clean package

FROM openjdk:17
WORKDIR /app
COPY --from=frontend /app/build /app/static
COPY --from=backend /app/target/*.jar app.jar
ENTRYPOINT ["java", "-jar", "app.jar"]

9. SSR vs SSG: Decision Matrix

Criteria SSR SSG
Performance (First Load) ⚠️ slower ✅ fast
SEO ✅ good ✅ good
Dynamic Data ✅ ideal ⚠️ limited
Scalability ⚠️ costly ✅ cacheable
Dev Complexity ⚠️ high ✅ simple

10. Summary

Now you know how to:

  • Enhance SSR with Express or use SSG for performance
  • Optimize hydration, caching, and SEO
  • Deploy the app using Docker and CI/CD

Whether you're building a blog, dashboard, or a public portal, these tools give you full control over rendering and performance.

Next: We’ll explore authentication, role-based views, and SSR-secured routes in Spring + React!

Add your comment