How to Implement StaticRouter in React
This article provides a straightforward guide on how to implement
StaticRouter in React for server-side rendering (SSR). You
will learn what StaticRouter is, why it is used to render
React applications on a server, and how to configure it alongside your
client-side routing to achieve seamless page hydration.
What is StaticRouter?
StaticRouter is a router provided by React Router
specifically for server-side rendering. Unlike
BrowserRouter, which reads the current location directly
from the browser’s address bar, StaticRouter is completely
stateless. It takes a specific URL provided by your server and uses it
to render the correct component tree matching that route.
In React Router v6, StaticRouter is imported from the
react-router-dom/server package.
Step 1: Install the Required Dependencies
To use StaticRouter, you need both
react-router-dom and the server-side utilities. Install
them in your project using npm or yarn:
npm install react-router-domStep 2: Create Your App Routes
Define your application components and routing structure. This file will be shared by both the server-side renderer and the client-side bundle.
// App.jsx
import React from 'react';
import { Routes, Route, Link } from 'react-router-dom';
const Home = () => <h2>Home Page</h2>;
const About = () => <h2>About Page</h2>;
export default function App() {
return (
<div>
<nav>
<Link to="/">Home</Link> | <Link to="/about">About</Link>
</nav>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
</Routes>
</div>
);
}Step 3: Implement StaticRouter on the Server
On the Node.js server (such as an Express server), you will intercept
incoming requests, pass the requested URL to StaticRouter
via the location prop, and render the application to an
HTML string using ReactDOMServer.renderToString.
// server.js
import express from 'express';
import React from 'react';
import ReactDOMServer from 'react-dom/server';
import { StaticRouter } from 'react-router-dom/server';
import App from './App.jsx';
const app = express();
app.get('*', (req, res) => {
// Capture the requested URL from the express request object
const location = req.url;
// Render the component tree using StaticRouter
const html = ReactDOMServer.renderToString(
<StaticRouter location={location}>
<App />
</StaticRouter>
);
// Send the rendered HTML template back to the client
res.send(`
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>React SSR</title>
</head>
<body>
<div id="root">${html}</div>
<script src="/bundle.js"></script>
</body>
</html>
`);
});
app.listen(3000, () => {
console.log('Server is running on http://localhost:3000');
});Step 4: Hydrate the Application on the Client
Once the browser receives the static HTML rendered by the server,
React needs to attach event listeners to make the page interactive. On
the client side, you must wrap the shared <App />
component in a <BrowserRouter> and use React’s
hydrateRoot method.
// client.js
import React from 'react';
import { hydrateRoot } from 'react-dom/client';
import { BrowserRouter } from 'react-router-dom';
import App from './App.jsx';
hydrateRoot(
document.getElementById('root'),
<BrowserRouter>
<App />
</BrowserRouter>
);By pairing StaticRouter on the server with
BrowserRouter on the client, you successfully implement
server-side rendering for a routing-heavy React application.