React and other similar libraries (like Vue.js) are becoming the de facto choice for larger businesses that require complex development where a more simplistic approach (like using a WordPress theme) won’t satisfy the requirements.
Still, some complexities remain, which I’ll run through in this guide.
On that note, here’s what we’ll cover:
The simplest way to understand the components is by thinking of them as plugins, like for WordPress. They allow developers to quickly build a design and add functionality to a page using component libraries like MUI or Tailwind UI.
If you want the full lowdown on why developers love React, start here:
React implements an App Shell Model, meaning the vast majority of content, if not all, will be Client-side Rendered (CSR) by default.
CSR means the HTML primarily contains the React JS library rather than the server sending the entire page’s contents within the initial HTTP response from the server (the HTML source).
If you don’t see many lines of HTML there, the application is likely client-side rendering.
The result is you’ll then see the site has a lot of HTML:
Note the appMountPoint ID on the first <div>. You’ll commonly see an element like that on a single-page application (SPA), so a library like React knows where it should inject HTML. Technology detection tools, e.g., Wappalyzer, are also great at detecting the library.
Ahrefs’ Site Audit saves both the Raw HTML sent from the server and the Rendered HTML in the browser, making it easier to spot whether a site has client-side rendered content.
Even better, you can search both the Raw and Rendered HTML to know what content is specifically being rendered client-side. In the below example, you can see this site is client-side rendering key page content, such as the <h1> tag.
Websites created using React differ from the more traditional approach of leaving the heavy-lifting of rendering content on the server using languages like PHP—called Server-side Rendering (SSR).
Before SSR, developers kept it even simpler.
They would create static HTML documents that didn’t change, host them on a server, and then send them immediately. The server didn’t need to render anything, and the browser often had very little to render.
In practice, SSR and SSG are similar.
The key difference is that rendering happens with SSR when a browser requests a URL versus a framework pre-rendering content at build time with SSG (when developers deploy new code or a web admin changes the site’s content).
SSR can be more dynamic but slower due to additional latency while the server renders the content before sending it to the user’s browser.
SSG is faster, as the content has already been rendered, meaning it can be served to the user immediately (meaning a quicker TTFB).
To understand why React’s default client-side rendering approach causes SEO issues, you first need to know how Google crawls, processes, and indexes pages.
We can summarize the basics of how this works in the below steps:
- Crawling – Googlebot sends GET requests to a server for the URLs in the crawl queue and saves the response contents. Googlebot does this for HTML, JS, CSS, image files, and more.
- Processing – This includes adding URLs to the crawl queue found within <a href> links within the HTML. It also includes queuing resource URLs (CSS/JS) found within <link> tags or images within <img src> tags. If Googlebot finds a noindex tag at this stage, the process stops, Googlebot won’t render the content, and Caffeine (Google’s indexer) won’t index it.
- Indexing – Caffeine takes the information from Googlebot, normalizes it (fixes broken HTML), and then tries to make sense of it all, precomputing some ranking signals ready for serving within a search result.
Historically, issues with React and other JS libraries have been due to Google not handling the rendering step well.
Some examples include:
- Google had a rendering delay – In some cases, this could mean a delay of up to a few weeks, slowing down the time for changes to the content to reach the indexing stage. This would have ruled out relying on Google to render content for most sites.
Thankfully, Google has now resolved most of these issues. Googlebot is now evergreen, meaning it always supports the latest features of Chromium.
In addition, the rendering delay is now five seconds, as announced by Martin Splitt at the Chrome Developer Summit in November 2019:
Last year Tom Greenaway and I were on this stage and telling you, ‘Well, you know, it can take up to a week, we are very sorry for this.’ Forget this, okay? Because the new numbers look a lot better. So we actually went over the numbers and found that, it turns out that at median, the time we spent between crawling and actually having rendered these results is – on median – it’s five seconds!”
This all sounds positive. But is client-side rendering and leaving Googlebot to render content the right strategy?
The answer is most likely still no.
It’s important to note that you can overcome all issues with React and SEO.
React JS is a development tool. React is no different from any other tool within a development stack, whether that’s a WordPress plugin or the CDN you choose. How you configure it will decide whether it detracts or enhances SEO.
Ultimately, React is good for SEO, as it improves user experience. You just need to make sure you consider the following common issues.
1. Pick the right rendering strategy
The most significant issue you’ll need to tackle with React is how it renders content.
Introducing this unknown builds a good case for opting for a server-side rendered solution to ensure that all crawlers can see the site’s content.
In addition, rendering content on the server has another crucial benefit: load times.
However, after the initial render by the browser, subsequent load times tend to be quicker due to the following:
Depending on the number of pages viewed per visit, this can result in field data being positive overall.
However, if your site has a low number of pages viewed per visit, you’ll struggle to get positive field data for all Core Web Vitals.
The best option is to opt for SSR or SSG mainly due to:
- Faster initial renders.
- Not having to rely on search engine crawlers to render content.
Implementing SSR within React is possible via ReactDOMServer. However, I recommend using a React framework called Next.js and using its SSG and SSR options. You can also implement CSR with Next.js, but the framework nudges users toward SSR/SSG due to speed.
Next.js supports what it calls “Automatic Static Optimization.” In practice, this means you can have some pages on a site that use SSR (such as an account page) and other pages using SSG (such as your blog).
The result: SSG and fast TTFB for non-dynamic pages, and SSR as a backup rendering strategy for dynamic content.
You may have heard about React Hydration with ReactDOM.hydrate(). This is where content is delivered via SSG/SSR and then turns into a client-side rendered application during the initial render. This may be the obvious choice for dynamic applications in the future rather than SSR. However, hydration currently works by loading the entire React library and then attaching event handlers to HTML that will change. React then keeps HTML between the browser and server in sync. Currently, I can’t recommend this approach because it still has negative implications for web vitals like TTI for the initial render. Partial Hydration may resolve this in the future by only hydrating critical parts of the page (like ones within the browser viewport) rather than the entire page; until then, SSR/SSG is the better option.
Since we’re talking about speed, I’ll be doing you a disservice by not mentioning other ways Next.js optimizes the critical rendering path for React applications with features like:
- Image optimization – This adds…