Skip to content
geeksforgeeks
  • Courses
    • DSA to Development
    • Get IBM Certification
    • Newly Launched!
      • Master Django Framework
      • Become AWS Certified
    • For Working Professionals
      • Interview 101: DSA & System Design
      • Data Science Training Program
      • JAVA Backend Development (Live)
      • DevOps Engineering (LIVE)
      • Data Structures & Algorithms in Python
    • For Students
      • Placement Preparation Course
      • Data Science (Live)
      • Data Structure & Algorithm-Self Paced (C++/JAVA)
      • Master Competitive Programming (Live)
      • Full Stack Development with React & Node JS (Live)
    • Full Stack Development
    • Data Science Program
    • All Courses
  • Tutorials
    • Data Structures & Algorithms
    • ML & Data Science
    • Interview Corner
    • Programming Languages
    • Web Development
    • CS Subjects
    • DevOps And Linux
    • School Learning
  • Practice
    • Build your AI Agent
    • GfG 160
    • Problem of the Day
    • Practice Coding Problems
    • GfG SDE Sheet
  • Contests
    • Accenture Hackathon (Ending Soon!)
    • GfG Weekly [Rated Contest]
    • Job-A-Thon Hiring Challenge
    • All Contests and Events
  • React Tutorial
  • React Exercise
  • React Basic Concepts
  • React Components
  • React Props
  • React Hooks
  • React Router
  • React Advanced
  • React Examples
  • React Interview Questions
  • React Projects
  • Next.js Tutorial
  • React Bootstrap
  • React Material UI
  • React Ant Design
  • React Desktop
  • React Rebass
  • React Blueprint
  • JavaScript
  • Web Technology
Open In App
Next Article:
Node.js Server Side Rendering (SSR) using EJS
Next article icon

Ultimate Guide to Server-Side Rendering (SSR) with Vite and ReactJS

Last Updated : 23 Sep, 2024
Comments
Improve
Suggest changes
Like Article
Like
Report

Server-side rendering (this practice allows making web pages since the browser only enables blank pages) can be defined as one of the current trends in web development. SSR offers many advantages – performance improvement, SEO enhancement, and even convenience for users. As opposed to client-side rendering only after the complete page is loaded, which can disappoint users with slower devices or networks, SSR allows for steaming pages during loading which is great on the large part of the slow pages.

Server-side-rendering

Below are the points to discuss in the article:

Table of Content

  • What is SSR?
  • Why SSR Matters?
  • Benefits of SSR in Modern Web Applications
  • Challenges and Considerations
  • Implementing SSR in React with Vite
  • Setting up a React Project with Vite and SSR
  • Approach to Create SSR Application
  • Routing with SSR
  • Data Fetching Strategies
  • Handling State Management
  • Optimizing Performance

What is SSR?

Server-side rendering (SSR) is a web application technique in which the HTML of web pages is generated on the server and then sent to the client. This method allows for faster initial page loads because the server prepares the content, reducing the time the browser spends processing JavaScript to render the page.

Why SSR Matters?

SSR significantly improves the performance and accessibility of web applications by pre-rendering the HTML on the server. This leads to faster load times and enhanced user experiences, particularly on slower devices or networks. Additionally, SSR improves the ability of search engines to index content, as the fully rendered HTML is readily available for crawling.

Benefits of SSR in Modern Web Applications

Alright. Instead, let’s see what is so special about its implementation that ought to come last.

  • Increased Speed: The main reason why content is thought to be able to deploy SSR, is that users are served content more quickly through this method as the page has been prepared at the server several cuts down TTFB as well as perceived load time. That is especially useful for users on a slow connection or running low on power.
  • SEO Optimization: Search engines have an easier time crawling and indexing HTML content rendered on the server. SSR improves visibility on search engines compared to client-rendered JavaScript content.
  • Enhanced Indexing: The crawlers or bots will find it easier to index the content that has been pre-rendered in the server in the structure of an HTML document. SSR enhances the reachability of the content than client-only rendered JavaScript content.
  • Better Accessibility: Content rendered on the server is more accessible to assistive technologies, which improves usability for users relying on screen readers or other aids.

Challenges and Considerations

  • Complexity: SSR requires more complex server configurations and an understanding of both server and client environments.
  • Performance Overhead: Rendering on the server can add load, making efficient caching strategies critical.
  • Hydration: Ensuring client-side JavaScript takes over the static HTML without issues can be tricky.

Implementing SSR in React with Vite

Vite is an app-building tool that provides fast build and development modes. It directly utilizes the ES modules of the browser for development and then uses Rollup to bundle the code for Production. From Vite’s side, it is reasonable to use it with frameworks, like React because of the HMR HOT replacement efficiency and processing speed.

On the other hand, React.js is a component-based library for building user interfaces. React allows developers to build encapsulated components that manage their state and then compose them to make complex user interfaces more efficient through changes in data.

Together, Vite and React provide the best combination for building performant and scalable web applications.

Setting up a React Project with Vite and SSR

Let’s start by setting up a new Vite project configured for React:

Step 1: Install Vite

First, create a new Vite project by running the following commands in your terminal:

npm create vite@latest

Step 2: Then Follow the below instructions

Choose the following options:

Other -> create-vite-extra -> ssr-react -> non-streaming -> javascript/typescript

Project Structure:

Screenshot-2024-09-08-230853
Project structure

Updated Dependencies:

  "dependencies": {
"compression": "^1.7.4",
"express": "^4.19.2",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"sirv": "^2.0.4"
},
"devDependencies": {
"@types/react": "^18.2.79",
"@types/react-dom": "^18.2.25",
"@vitejs/plugin-react": "^4.2.1",
"cross-env": "^7.0.3",
"vite": "^5.2.10"
}
  • Now that you have the package.json and list of dependencies, let's walk through the entire setup process, including configuring Vite for SSR and creating the basic server file.
  • To install all the necessary dependencies, run the following command in your project directory:
npm install

Approach to Create SSR Application

Vite requires some configuration changes to support SSR. We will need to set up a server entry point and modify the Vite configuration file.

Step 1: Create a Server Entry File

Started by creating a new file named server.js in the root of your project. This file will handle server-side rendering and serve your React application.

To implement SSR effectively, you need to set up the server to render your React components and manage routing correctly.

  • Server-Side Rendering: Use renderToString from react-dom/server to render your React components on the server side.
  • Serve the HTML: In the server response, send the fully rendered HTML along with a script tag that points to your client-side JavaScript entry point.
JavaScript
import express from "express" import fs from "node:fs/promises"  // Constants const isProduction = process.env.NODE_ENV === "production" const port = process.env.PORT || 5173 const base = process.env.BASE || "/"  // Cached production assets const templateHtml     = isProduction ? await fs.readFile(           "./dist/client/index.html", "utf-8")                    : "" const ssrManifest     = isProduction ? await fs.readFile(           "./dist/client/.vite/ssr-manifest.json", "utf-8")                    : undefined  // Create http server const app = express()  // Add Vite or respective production middlewares let vite if (!isProduction) {     const {createServer} = await import("vite")     vite = await createServer({         server : {middlewareMode : true},         appType : "custom",         base     })     app.use(vite.middlewares) } else {     const compression     = (await import("compression")).default const sirv     = (await import("sirv")).default app.use(compression())   app.use(base, sirv("./dist/client", { extensions: [] })) }  // Serve HTML app.use("*", async (req, res) => {     try {         const url = req.originalUrl.replace(base, "")          let template let render         if (!isProduction)         {             // Always read fresh template in development             template = await fs.readFile("./index.html",                                          "utf-8") template                 = await vite.transformIndexHtml(url,                                                 template)             render = (await vite.ssrLoadModule(                           "/src/entry-server.jsx"))                          .render         }         else         {             template = templateHtml             render = (await import(                           "./dist/server/entry-server.js"))                          .render         }          const rendered = await render(url, ssrManifest)      const html = template       .replace(`<!--app-head-->`, rendered.head ?? "")       .replace(`<!--app-html-->`, rendered.html ?? "")      res.status(200)         .set({"Content-Type" : "text/html"})         .send(html)     }     catch (e) {         vite?.ssrFixStacktrace(e)         console.log(e.stack)         res.status(500).end(e.stack)     } })    // Start http server   app.listen(       port,       () => {console.log(           `Server started at http://localhost:${port}`)}) 

This basic Express server renders your React application using renderToString and serves the generated HTML to the client.

Step 2: src/entry-client.jsx: Set up client-side hydration

This code will sets up the entry point for a React application with server-side rendering support. It imports the necessary CSS and React libraries, then uses ReactDOM.hydrateRoot to attach the React app to an existing HTML element that was pre-rendered on the server. Wrapping the app in React.StrictMode helps identify potential issues during development by providing additional checks and warnings. The BrowserRouter component from react-router-dom enables client-side routing, allowing seamless navigation between different views without full page reloads. Inside the BrowserRouter, the Router component (imported from the local ./router module) manages the application's routes and navigation logic, ensuring a smooth and interactive user experience.

JavaScript
import "./index.css" import React from "react" import ReactDOM from "react-dom/client" import {BrowserRouter} from "react-router-dom" import {Router} from "./router"  ReactDOM.hydrateRoot(document.getElementById("root"),                      <React.StrictMode><BrowserRouter>                      <Router />                      </BrowserRouter> </React.StrictMode>) 

Step 3: src/entry-server.jsx: Set up server-side rendering

This code snippet will sets up server-side rendering for a React application. It imports necessary modules from React and React Router, specifically ReactDOMServer for rendering React components to a static HTML string and StaticRouter for handling routing on the server side.

The render function uses ReactDOMServer.renderToString to convert the React component tree into an HTML string. The StaticRouter component, which is part of react-router-dom/server, manages the routing based on the server-side location prop (though path should be defined or passed in a real scenario). The React.StrictMode wrapper is used for development checks. Finally, the function returns an object containing the generated HTML, which can be sent to the client to be rendered in the browser.

JavaScript
import React from "react" import ReactDOMServer from "react-dom/server" import {StaticRouter} from "react-router-dom/server"; import {Router} from "./router"  export function render() {     const html = ReactDOMServer.renderToString(         <React.StrictMode><StaticRouter location = {path}>         <Router /></StaticRouter>     </React.StrictMode>)     return { html } } 

Step 4: Build and Run the Application

Build the Application:

npm run build
npm run build:client
npm run build:server

This command builds the client and server parts of the application.

Run the application:

npm run dev

Your server will start at http://localhost:5173, serving the SSR React application.

Screenshot-2024-09-08-233318
output

Routing with SSR

With SSR, routing must be handled on both the server and the client. On the server, use StaticRouter from react-router-dom/server to render the correct routes based on the incoming request URL. On the client side, use BrowserRouter to handle navigation without a full page reload.

Step 1: Create a router.jsx file inside the src folder of the application

This code defines a simple routing setup for a React application using react-router-dom. It imports the Route and Routes components to configure routing, and it also imports the Contact and Home components from the views directory.

The Router component sets up the routing configuration by defining a set of routes within the Routes component. It maps the root path ("/") to the Home component and the /contact path to the Contact component. This setup allows users to navigate between the home page and the contact page within the application.

JavaScript
import {Route, Routes} from "react-router-dom";  import {Contact, Home} from "../views";  export const Router = () => {   return (     <Routes>       <Route path="/" element={<Home />} />       <Route path="/contact" element={<Contact />} />     </Routes>   ); }; 

Step 2: Update the entry-client.jsx

JavaScript
import "./index.css"  import React from "react" import ReactDOM from "react-dom/client" import {BrowserRouter} from "react-router-dom"  import {Router} from "./router"  ReactDOM.hydrateRoot(document.getElementById("root"),                      <React.StrictMode><BrowserRouter>                      <Router />                      </BrowserRouter>   </React.StrictMode>) 

Step 3: Update the entry-server.jsx

JavaScript
import React from "react" import ReactDOMServer from "react-dom/server" import {StaticRouter} from "react-router-dom/server"; import {Router} from "./router"  export function render() {     const html = ReactDOMServer.renderToString(         <React.StrictMode><StaticRouter location = {path}>         <Router /></StaticRouter>     </React.StrictMode>)     return { html } } 

Data Fetching Strategies

  • Handling data fetching in SSR can be complex but crucial for performance and user experience. You can use libraries like react-query or implement custom hooks that support server-side data fetching.
  • Fetch data before rendering the component on the server. Pass the fetched data as props to your components.
  • Ensure that the data fetched on the server is available to the client during hydration to prevent duplication of requests.

Handling State Management

Integrate state management solutions like Redux, Zustand, or Context API to manage application state across server and client. Ensure the initial state is serialized and included in the HTML sent from the server.

Optimizing Performance

  • Code Splitting: This can be achieved in the following ways – by utilizing lazy loads provided by the react frameworks and dynamic imports in Vite.
  • Caching: Aim of this strategy is to reduce the load on the server and improve its performance by creating caches of rendered HTML pages and other static files.
  • Minification and Compression: This performs several elementary operations such as: javascript minification with the usage of terser, and gzip or brotli as a response pack.

Next Article
Node.js Server Side Rendering (SSR) using EJS
author
amangfg
Improve
Article Tags :
  • GBlog
  • Web Technologies
  • ReactJS
  • Web-Tech Blogs

Similar Reads

  • Server-Side Rendering (SSR) with React Hooks
    Server-side rendering (SSR) is a technique used to render web pages on the server side and send the fully rendered page to the client's browser. This approach offers benefits such as improved SEO and faster initial page loads. With the introduction of React Hooks, SSR implementation has become even
    4 min read
  • Server Side Rendering using Express.js And EJS Template Engine
    Server-side rendering involves generating HTML on the server and sending it to the client, as opposed to generating it on the client side using JavaScript. This improves initial load time, and SEO, and enables dynamic content generation. Express is a popular web application framework for NodeJS, and
    3 min read
  • How to Set Up Vite for Server-Side Rendering (SSR)?
    Vite is a build tool that can be integrated with most modern JS web frameworks like React, Vue, Next.js, or even vanillaJS, and offers a variety of features like Hot Module Reloading (HMR), etc. In this article, we will learn how to setup vite using vanillaJS and SSR. Steps to Set Up Vite for Server
    2 min read
  • Importance of View Engines in server-side rendering(SSR)
    A view engine is a tool used in web development to create dynamic HTML content based on data from the server. It acts as a template processor that allows you to integrate data with predefined HTML templates easily. In this article, we will learn about the Importance of view engines on server side re
    3 min read
  • Node.js Server Side Rendering (SSR) using EJS
    Server-side rendering (SSR) is a popular technique for rendering a normally client-side-only single-page app (SPA) on the server and then sending a fully rendered page to the client. The client's JavaScript bundle can then take over and the SPA can operate as normal. SSR technique is helpful in situ
    3 min read
  • Is Server Side Rendering(SSR) always good ?
    SSR is a technique used in web development where the HTML of a webpage is generated on the server rather than in the browser. This means when a user requests a webpage, the server prepares the HTML document by executing the necessary logic and sends it to the client’s browser, fully formed and ready
    5 min read
  • How to Disable Server Side Rendering on Some Pages in Next.js ?
    In Next.js 13 and above versions you can use the 'use client' directive to disable the server side rendering and enable the client side rendering for some specific pages or components. This directive indicates that the code should be executed on clint side only. Prerequisites :NodejsNext.js, ReactJs
    3 min read
  • How to Set Up Vite with ESLint and Prettier?
    Integrating ESLint and Prettier is important to maintaining consistent code quality and style across a Vite project. Prettier ensures uniform code formatting, while ESLint assists in locating and resolving possible coding errors. Along with various methods and folder structures, this article will wa
    1 min read
  • Server-Side Rendering in Angular
    With fast and efficient web applications, developers are continually seeking ways to enhance performance, user experience, and search engine optimization (SEO). One such strategy is server-side rendering (SSR). In this article, we will see what SSR is, why it is important, and how to implement it in
    5 min read
  • What is the Difference Between "vite" and "vite preview"?
    Vite is a build tool designed for modern web projects, offering a fast and efficient development environment. It features rapid hot module replacement (HMR), so you can instantly see updates as you change your code. This makes Vite ideal for developers who need a quick and responsive development set
    3 min read
geeksforgeeks-footer-logo
Corporate & Communications Address:
A-143, 7th Floor, Sovereign Corporate Tower, Sector- 136, Noida, Uttar Pradesh (201305)
Registered Address:
K 061, Tower K, Gulshan Vivante Apartment, Sector 137, Noida, Gautam Buddh Nagar, Uttar Pradesh, 201305
GFG App on Play Store GFG App on App Store
Advertise with us
  • Company
  • About Us
  • Legal
  • Privacy Policy
  • In Media
  • Contact Us
  • Advertise with us
  • GFG Corporate Solution
  • Placement Training Program
  • Languages
  • Python
  • Java
  • C++
  • PHP
  • GoLang
  • SQL
  • R Language
  • Android Tutorial
  • Tutorials Archive
  • DSA
  • Data Structures
  • Algorithms
  • DSA for Beginners
  • Basic DSA Problems
  • DSA Roadmap
  • Top 100 DSA Interview Problems
  • DSA Roadmap by Sandeep Jain
  • All Cheat Sheets
  • Data Science & ML
  • Data Science With Python
  • Data Science For Beginner
  • Machine Learning
  • ML Maths
  • Data Visualisation
  • Pandas
  • NumPy
  • NLP
  • Deep Learning
  • Web Technologies
  • HTML
  • CSS
  • JavaScript
  • TypeScript
  • ReactJS
  • NextJS
  • Bootstrap
  • Web Design
  • Python Tutorial
  • Python Programming Examples
  • Python Projects
  • Python Tkinter
  • Python Web Scraping
  • OpenCV Tutorial
  • Python Interview Question
  • Django
  • Computer Science
  • Operating Systems
  • Computer Network
  • Database Management System
  • Software Engineering
  • Digital Logic Design
  • Engineering Maths
  • Software Development
  • Software Testing
  • DevOps
  • Git
  • Linux
  • AWS
  • Docker
  • Kubernetes
  • Azure
  • GCP
  • DevOps Roadmap
  • System Design
  • High Level Design
  • Low Level Design
  • UML Diagrams
  • Interview Guide
  • Design Patterns
  • OOAD
  • System Design Bootcamp
  • Interview Questions
  • Inteview Preparation
  • Competitive Programming
  • Top DS or Algo for CP
  • Company-Wise Recruitment Process
  • Company-Wise Preparation
  • Aptitude Preparation
  • Puzzles
  • School Subjects
  • Mathematics
  • Physics
  • Chemistry
  • Biology
  • Social Science
  • English Grammar
  • Commerce
  • World GK
  • GeeksforGeeks Videos
  • DSA
  • Python
  • Java
  • C++
  • Web Development
  • Data Science
  • CS Subjects
@GeeksforGeeks, Sanchhaya Education Private Limited, All rights reserved
We use cookies to ensure you have the best browsing experience on our website. By using our site, you acknowledge that you have read and understood our Cookie Policy & Privacy Policy
Lightbox
Improvement
Suggest Changes
Help us improve. Share your suggestions to enhance the article. Contribute your expertise and make a difference in the GeeksforGeeks portal.
geeksforgeeks-suggest-icon
Create Improvement
Enhance the article with your expertise. Contribute to the GeeksforGeeks community and help create better learning resources for all.
geeksforgeeks-improvement-icon
Suggest Changes
min 4 words, max Words Limit:1000

Thank You!

Your suggestions are valuable to us.

What kind of Experience do you want to share?

Interview Experiences
Admission Experiences
Career Journeys
Work Experiences
Campus Experiences
Competitive Exam Experiences