I would like to serve a react project from the nodejs server. I encountered the two ways of doing it:
The first way is to use express to serve just the build folder for whatever the req made:
const express = require('express')
const app = express()
const path = require('path')
app.use(express.static(path.join(__dirname,'build')))
app.get('*',function(req,res){
res.sendFile(path.join(__dirname,'build','index.html'))
})
module.exports = app;
The second way is one using ReactDOM.hydrate
and ReactDOMServer.renderToString
to serve the app. It is described here.
What is best way to achieve the good SEO from the above mentioned ways and when to choose one over other?
Thank you!!!
2
Answers
React renders on the client side by default. Most search engine bots however, cannot read JavaScript. Therefore, using server-side rendering is better for SEO, because it generates a static HTML file on the server, which is then served to the client.
Another difference is that client-side rendering will take longer to load the first time, but all consecutive times it will render faster (if the client didn’t disable cache). A server-side rendered website has to render the page everytime it loads on the server. Making it slightly slower on average, but will provide consistent loading speeds and a faster first-time loading speed which is important for business landing pages as an example.
CSR
The first approach, where you just serve the
build
folder and direct all the requests toindex.html
is a default way of how single-page applications (SPA) work. This approach is called Client Side Rendering (CSR), meaning that client (browser) will be responsible for preparing all the content of your website via executing javascript code of your application, then fetch all the data from API (news, posts, profile, etc.) and, finally, build the page layout and display everything on the screen.SSR
In turn, with the second approach you mentioned, server prepares (renders) the whole document (HTML) with content and sends it to the client which only needs to display it. This is called Server Side Rendering (SSR) and in your case the
ReactDOMServer
is responsible for that. However, since you want your application to be interactive, you need to "revive" it with javascript (in our case with React) and that is whatReactDOM.hydrate
actually does. It appends all the necessary event listeners to existing markup and makes page to behave in the way it would behave if it was fully rendered on the client (default CSR).SEO
There is a general opinion that using CSR has a bad impact on SEO because bots crawling the site need to perform additional steps (execute javascript) and it slows down the process and make it less efficient, moreover, not all the bots can run javascript at all.
However, nowadays, modern crawlers (e.g. Google) can cope with SPA quite good, but the end results might be not as good as with SSR.
If you are at the beginning of project development and SEO is really a very high priority for you, then you should choose SSR.
However, instead of implementing everything yourself with
ReactDOMServer
andhydrate
, I’d recommend you to take a look at the Next.js – it is powerful and easy to learn React framework.P.S.
SSG
You also should be aware of the Static Site Generation (SSG) approach, where every single page of your application gets prerendered at the build stage, producing bunch of HTML files and other assets of your site. Then, all those static files are served from a simple hosting and/or CDN. The main benefits of such approach are: very high speed of page loading, great SEO and usually very low cost for maintenance.
However, this approach suits only sites where content changes very rarely and pages are not interactive. Of course, you may combine it with hydration, but it often leads to quite tricky and buggy solutions in the end.
You can read more details about all three approaches here.