[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"navigation":3,"\u002Fblog\u002Fa-guide-to-server-side-rendering-ssr-with-vite-and-reactjs":58,"\u002Fblog\u002Fa-guide-to-server-side-rendering-ssr-with-vite-and-reactjs-surround":293},[4],{"title":5,"path":6,"stem":7,"children":8,"page":57},"Blog","\u002Fblog","blog",[9,13,17,21,25,29,33,37,41,45,49,53],{"title":10,"path":11,"stem":12},"A Guide to Server-Side Rendering (SSR) with Vite and React.js","\u002Fblog\u002Fa-guide-to-server-side-rendering-ssr-with-vite-and-reactjs","blog\u002Fa-guide-to-server-side-rendering-ssr-with-vite-and-reactjs",{"title":14,"path":15,"stem":16},"🔄 Background DNS Refresh in Node.js: Keeping Cached IPs Updated","\u002Fblog\u002Fbackground-dns-refresh-in-nodejs-keeping-cached-ips-updated","blog\u002Fbackground-dns-refresh-in-nodejs-keeping-cached-ips-updated",{"title":18,"path":19,"stem":20},"Comprehensive Guide: Encrypting Images, Uploading to Cloudinary, and Serving Them Securely","\u002Fblog\u002Fcomprehensive-guide-encrypting-images-uploading-to-cloudinary-and-serving-them-securely","blog\u002Fcomprehensive-guide-encrypting-images-uploading-to-cloudinary-and-serving-them-securely",{"title":22,"path":23,"stem":24},"Comprehensive Guide to Using Uploadthing with Express and Typescript","\u002Fblog\u002Fcomprehensive-guide-to-using-uploadthing-with-express-and-typescript","blog\u002Fcomprehensive-guide-to-using-uploadthing-with-express-and-typescript",{"title":26,"path":27,"stem":28},"🌐 DNS Caching in Node.js: Supercharge Your App's Speed & Reliability 🚀","\u002Fblog\u002Fdns-caching-in-nodejs-supercharge-your-apps-speed-and-reliability","blog\u002Fdns-caching-in-nodejs-supercharge-your-apps-speed-and-reliability",{"title":30,"path":31,"stem":32},"Enhancing Redis for Message Queues: Using External Databases for Payload Storage","\u002Fblog\u002Fenhancing-redis-for-message-queues-using-external-databases-for-payload-storage","blog\u002Fenhancing-redis-for-message-queues-using-external-databases-for-payload-storage",{"title":34,"path":35,"stem":36},"Full Stack Learning Management System (LMS) with MERN Stack: A Complete Guide","\u002Fblog\u002Ffull-stack-learning-management-system-lms-with-mern-stack-a-complete-guide","blog\u002Ffull-stack-learning-management-system-lms-with-mern-stack-a-complete-guide",{"title":38,"path":39,"stem":40},"Getting Started with Redis: Elevating Your Web Applications","\u002Fblog\u002Fgetting-started-with-redis-elevating-your-web-applications","blog\u002Fgetting-started-with-redis-elevating-your-web-applications",{"title":42,"path":43,"stem":44},"How Queues Enhance Your Application Development Process","\u002Fblog\u002Fhow-queues-enhance-your-application-development-process","blog\u002Fhow-queues-enhance-your-application-development-process",{"title":46,"path":47,"stem":48},"Next-Gen E-Learning: Transforming Education for Students and Creators","\u002Fblog\u002Fnext-gen-e-learning-transforming-education-for-students-and-creators","blog\u002Fnext-gen-e-learning-transforming-education-for-students-and-creators",{"title":50,"path":51,"stem":52},"Single Sign-On (SSO) Implementation Using Passport.js in TypeScript","\u002Fblog\u002Fsingle-sign-on-sso-implementation-using-passportjs-in-typescript","blog\u002Fsingle-sign-on-sso-implementation-using-passportjs-in-typescript",{"title":54,"path":55,"stem":56},"Using Multer for Local File Uploads: Benefits, Trade-offs, and Cloud Transfer Integration","\u002Fblog\u002Fusing-multer-for-local-file-uploads-benefits-trade-offs-and-cloud-transfer-integration","blog\u002Fusing-multer-for-local-file-uploads-benefits-trade-offs-and-cloud-transfer-integration",false,{"id":59,"title":10,"author":60,"body":66,"date":285,"description":286,"extension":287,"image":288,"meta":289,"minRead":280,"navigation":290,"path":11,"seo":291,"stem":12,"__hash__":292},"blog\u002Fblog\u002Fa-guide-to-server-side-rendering-ssr-with-vite-and-reactjs.md",{"name":61,"to":62,"username":63,"avatar":64},"Sachin Thapa","https:\u002F\u002Fsachinthapa.hashnode.dev\u002F","sachinthapa572",{"src":65,"alt":61},"https:\u002F\u002Fcdn.hashnode.com\u002Fres\u002Fhashnode\u002Fimage\u002Fupload\u002Fv1733546636355\u002Fa4ae8ce5-eb4c-4ed8-ab9d-15a4b8f32ea5.png",{"type":67,"value":68,"toc":276},"minimark",[69,76,79,84,87,89,93,96,99,121,123,127,130,132,136,139,144,152,162,180,187,196,202,206,220,226,230,233,239,243,250,256,258,262,265,268,270],[70,71,72],"p",{},[73,74,75],"strong",{},"Title: A Guide to Server-Side Rendering (SSR) with Vite and React.js",[77,78],"hr",{},[80,81,83],"h3",{"id":82},"introduction","Introduction",[70,85,86],{},"Server-Side Rendering (SSR) has become an essential technique for enhancing the performance and user experience of modern web applications. By pre-rendering pages on the server, SSR can drastically improve page load speeds and make websites more SEO-friendly. In this guide, we’ll explore how to implement SSR with React.js and Vite, step by step.",[77,88],{},[80,90,92],{"id":91},"what-is-server-side-rendering-ssr","What is Server-Side Rendering (SSR)?",[70,94,95],{},"In traditional client-side rendering (CSR), when a user visits a webpage, they receive a bare HTML page which then loads JavaScript and other resources, like CSS files. Only after these resources are loaded does the content become visible to the user. While this approach works, it can create delays in page load time, especially for users on slow connections.",[70,97,98],{},"SSR addresses this issue by rendering the HTML on the server, sending a fully rendered page to the client, and allowing the user to see the content immediately without waiting for JavaScript to load. This offers several benefits:",[100,101,102,109,115],"ul",{},[103,104,105,108],"li",{},[73,106,107],{},"Faster initial page load",": The user sees content more quickly because the server sends a complete HTML document.",[103,110,111,114],{},[73,112,113],{},"Better SEO",": Since search engines can crawl the fully rendered HTML, the content is indexed more effectively.",[103,116,117,120],{},[73,118,119],{},"Improved user experience",": The user can interact with content sooner, leading to higher engagement rates.",[77,122],{},[80,124,126],{"id":125},"performance-considerations-with-ssr","Performance Considerations with SSR",[70,128,129],{},"While SSR reduces the time to the Largest Contentful Paint (LCP), it can potentially increase the Interaction to Next Paint (INP), which is the time it takes for the user to interact with the page. A poorly implemented SSR setup might result in users seeing content but being unable to interact with it until the necessary JavaScript has loaded. It’s important to strike a balance between fast rendering and interactive elements to ensure smooth user interactions.",[77,131],{},[80,133,135],{"id":134},"steps-to-set-up-ssr-in-vite-and-reactjs","Steps to Set Up SSR in Vite and React.js",[70,137,138],{},"We’ll break down the implementation of SSR in a Vite and React.js project into a few manageable steps.",[140,141,143],"h4",{"id":142},"_1-create-a-clientapp-component","1. Create a ClientApp Component",[70,145,146,147,151],{},"First, we need to create a ",[148,149,150],"code",{},"ClientApp.jsx"," component to handle the client-side rendering logic.",[153,154,159],"pre",{"className":155,"code":157,"language":158},[156],"language-text","\u002F\u002F ClientApp.jsx\nimport { hydrateRoot } from 'react-dom\u002Fclient';\nimport { BrowserRouter } from 'react-router-dom';\nimport App from '.\u002FApp';\n\nhydrateRoot(document.getElementById('root'), \n  \u003CBrowserRouter>\n    \u003CApp \u002F>\n  BrowserRouter>\n);\n","text",[148,160,157],{"__ignoreMap":161},"",[70,163,164,165,168,169,172,173,168,176,179],{},"This code imports ",[148,166,167],{},"hydrateRoot"," from ",[148,170,171],{},"react-dom\u002Fclient"," and ",[148,174,175],{},"BrowserRouter",[148,177,178],{},"react-router-dom"," to ensure the React application is correctly rendered in the browser.",[140,181,183,184],{"id":182},"_2-modify-indexhtml","2. Modify ",[148,185,186],{},"index.html",[70,188,189,190,192,193,195],{},"Next, we need to update the ",[148,191,186],{}," file to load the ",[148,194,150],{}," file and add a parsing token to facilitate streaming.",[153,197,200],{"className":198,"code":199,"language":158},[156],"html>\n\u003Chtml lang=\"en\">\n  \u003Chead>\n    \u003Cmeta charset=\"UTF-8\" \u002F>\n    \u003Cmeta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" \u002F>\n    \u003Ctitle>Vite + React + SSRtitle>\n  head>\n  \u003Cbody>\n    \u003Cdiv id=\"root\">div>\n    \u003Cscript type=\"module\" src=\".\u002Fsrc\u002FClientApp.jsx\">script>\n  body>\nhtml>\n",[148,201,199],{"__ignoreMap":161},[140,203,205],{"id":204},"_3-create-a-serverapp-component","3. Create a ServerApp Component",[70,207,208,209,212,213,168,216,219],{},"Now, we’ll create a ",[148,210,211],{},"ServerApp.jsx"," file for the server-side rendering logic. It will use ",[148,214,215],{},"renderToPipeableStream",[148,217,218],{},"react-dom\u002Fserver"," to stream the HTML.",[153,221,224],{"className":222,"code":223,"language":158},[156],"\u002F\u002F ServerApp.jsx\nimport { renderToPipeableStream } from 'react-dom\u002Fserver';\nimport { StaticRouter } from 'react-router-dom\u002Fserver';\nimport App from '.\u002FApp';\n\nexport default function render(url, opts) {\n  const stream = renderToPipeableStream(\n    \u003CStaticRouter location={url}>\n      \u003CApp \u002F>\n    StaticRouter>,\n    opts\n  );\n\n  return stream;\n}\n",[148,225,223],{"__ignoreMap":161},[140,227,229],{"id":228},"_4-update-build-scripts","4. Update Build Scripts",[70,231,232],{},"To build both the client and server bundles, we need to update the build scripts.",[153,234,237],{"className":235,"code":236,"language":158},[156],"{\n  \"scripts\": {\n    \"build:client\": \"vite build --outDir ..\u002Fdist\u002Fclient\",\n    \"build:server\": \"vite build --outDir ..\u002Fdist\u002Fserver --ssr ServerApp.jsx\",\n    \"build\": \"npm run build:client && npm run build:server\",\n    \"start\": \"node server.js\"\n  },\n  \"type\": \"module\"\n}\n",[148,238,236],{"__ignoreMap":161},[140,240,242],{"id":241},"_5-set-up-the-nodejs-server","5. Set Up the Node.js Server",[70,244,245,246,249],{},"We need to set up an Express server in ",[148,247,248],{},"server.js"," to handle SSR and static assets.",[153,251,254],{"className":252,"code":253,"language":158},[156],"\u002F\u002F server.js\nimport express from 'express';\nimport fs from 'fs';\nimport path from 'path';\nimport { fileURLToPath } from 'url';\nimport renderApp from '.\u002Fdist\u002Fserver\u002FServerApp.js';\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\nconst PORT = process.env.PORT || 3001;\n\nconst html = fs.readFileSync(path.resolve(__dirname, '.\u002Fdist\u002Fclient\u002Findex.html')).toString();\nconst [head, tail] = html.split('');\n\nconst app = express();\n\n\u002F\u002F Serve static assets\napp.use('\u002Fassets', express.static(path.resolve(__dirname, '.\u002Fdist\u002Fclient\u002Fassets')));\n\n\u002F\u002F Handle all other routes with SSR\napp.use((req, res) => {\n  res.write(head);\n\n  const stream = renderApp(req.url, {\n    onShellReady() {\n      stream.pipe(res);\n    },\n    onShellError(err) {\n      console.error(err);\n      res.status(500).send('Internal Server Error');\n    },\n    onAllReady() {\n      res.write(tail);\n      res.end();\n    },\n    onError(err) {\n      console.error(err);\n    }\n  });\n});\n\napp.listen(PORT, () => {\n  console.log(`Server is running at http:\u002F\u002Flocalhost:${PORT}`);\n});\n",[148,255,253],{"__ignoreMap":161},[77,257],{},[80,259,261],{"id":260},"conclusion","Conclusion",[70,263,264],{},"By following these steps, we can implement server-side rendering (SSR) with React.js and Vite to improve the performance of our web application. The key benefit of SSR is that it reduces load times by delivering a fully rendered HTML page to the user. By streamlining content delivery, we create a faster, more responsive user experience.",[70,266,267],{},"This guide covered setting up SSR with React.js using Vite, creating necessary components, building server and client bundles, and configuring an Express server to handle SSR. With these optimizations in place, your application will be ready for better performance, enhanced SEO, and improved user engagement.",[77,269],{},[70,271,272],{},[273,274,275],"em",{},"Ready to optimize your React app with SSR? Follow these steps and watch your app's performance soar!",{"title":161,"searchDepth":277,"depth":277,"links":278},2,[279,281,282,283,284],{"id":82,"depth":280,"text":83},3,{"id":91,"depth":280,"text":92},{"id":125,"depth":280,"text":126},{"id":134,"depth":280,"text":135},{"id":260,"depth":280,"text":261},"2025-01-07","Learn to implement Server-Side Rendering (SSR) with React.js and Vite for improved web performance and SEO","md","https:\u002F\u002Fcdn.hashnode.com\u002Fres\u002Fhashnode\u002Fimage\u002Fupload\u002Fv1736255453305\u002F5d8c01c4-0478-4570-a0d2-8a343c1c17b4.png",{},true,{"title":10,"description":286},"wmeFga7yYi5CzVsu08SA1JwvarTSRUsWMuFsLgjhZgc",[294,295],null,{"title":14,"path":15,"stem":16,"description":296,"children":-1},"Learn how to implement background DNS refresh in Node.js to maintain consistent performance and eliminate latency spikes in high-traffic applications"]