Is React client side SEO friendly or not?

Is React client-side rendering SEO friendly to Google crawl bots?

This is a question that most SEO marketing experts, developers, and even myself have.

According to Martin Splitt, a Google developer, who explains SEO techniques for JavaScript, said in March 2019 that client-side rendering is SEO friendly.

How does google crawl a site and JavaScript?

A Google crawl bot will hit your site in two waves.

During the first wave, a crawl bot will hit your site and process the initial HTML that is served by the server.

This wave is instant, and gets indexed on the first day. The content being rendered via JavaScript will not be indexed during this phase.

Google craw bot process for JavaScript SEO

Content being rendered on the client-side will get crawled on the second wave.

According to Martin Splitt, this wave can take days to get indexed.

I wanted to put this to the test.

The experiment: Index my React client-side content

The test is simple and ran on my personal site.

Create a blank shell HTML file, and let some React code render content via client-side.

And observe how the Google crawl bots handles this.

Step 1: Create blank HTML

Linguine Code is built on Next.JS. All I had to do was create a blank shell page.


import * as React from 'react';
import Head from 'next/head';

const ReactSEOFriendly = () => {
  return (
    <>
      <Head>
        <title>React client side SEO friendly content</title>
        <meta name="description" content="This page shows if React client side is friendly in the initial render." />
        <script crossOrigin="true" src="https://unpkg.com/react@16/umd/react.development.js" />
        <script crossOrigin="true" src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" />
        <script src="https://cdn.jsdelivr.net/npm/create-react-class@15.6.3/create-react-class.min.js" />
      </Head>
      <div id="seo-client-side" />
      <script src="/js/react-compile.js"/>
    </>
  )
}

export default ReactSEOFriendly;

In this file, I’m importing the React scripts and my compiled React code that will render my content.

Step 2: Render content with React


(function() {
  window.onload = function() {
    if (React &&  ReactDOM) {
      class Container extends React.Component {

        constructor(props) {
          super(props);
          this.state = {
            showDescNow: false,
            showDeferDesc2: false,
          };
        }

        componentDidMount() {
          this.setState({ showDescNow: true });

          setTimeout(() => {
            this.setState({
              showDeferDesc2: true,
            })
          }, 5000);
        }

        render() {
          return (
            <React.Fragment>
              <h1>This text shows all the time.</h1>
              {this.state.showDescNow && <h2>This text shows after component has mounted.</h2>}
              {this.state.showDeferDesc2 && <h3>This text shows 5 seconds after component has mounted.</h3>}
            </React.Fragment>
          )
        }
      }

      ReactDOM.render(<Container />, document.getElementById('seo-client-side'));
    }
  }
})()

One thing to note is that I’m rendering parts of the content as 3 given times.

  1. Instant
  2. After the componentDidMount lifecycle
  3. 5 seconds later once the component has mounted

My goal here was to see if I can make the crawl bot not index parts of the content.

My expectations was that it would get the instant copy right away.


<h1>This text shows all the time.</h1>

The other part of the content was displayed a few milliseconds after the React code has been parsed, and executed


<h2>This text shows after component has mounted.</h2>

The last part of the content was a big delay of 5 seconds. This was to try an emulate an API call to fetch data, with a long response time.


<h3>This text shows 5 seconds after component has mounted.</h3>

Step 3: Tell Google to queue an index

This step had to happen in the Google Search Console.

I told Google to test my live page, and queue a crawl.

Google search console screenshot of React client side page

I was shocked to see that 2 parts of the content was picked up on the screenshot tab after it ran the view tested page.

And it also looked like the big 5 second content delay portion did not get picked up.

The results: Check Google search for React SEO friendly page

20 minutes later, I decided to go the Google search and search for

And here were the search results

React client side SEO friendly page index result

I was honestly shocked, that

  1. Google indexed the React content so quickly
  2. It indexed the 5 second delay portion of the content

Is React good or bad for SEO?

That’s a really hard question. Clearly the results above show that React rendered content can be indexed, even with lengthy delays.

But when you’re building a React page, it’s usually a single page application.

The behavior of links is completely different than if it was server-side rendered.

And link building (internal or external) plays a big factor in the SEO world. You have to be very careful how you build links in React.

Google crawl bots does NOT interact with content that gets triggered by some human interaction like clicking, scrolling or hovering.

For example, you can’t do this in React if you want Google to crawl your page properly


const PageWithLinks = () => (
  <>
    <a onClick={goTo('/page/url')}>Just don't</a>
    <a href="/page/url" onClick={goTo('/different/page')}>Don't do this either!</a>
    <span onClick={goTo('/different/page')}>This a big WTF!</span>
  </>
);

These are good React link practices


const PageWithLinks = () => (
  <>
    <a href="/page/url">This works! It just defeats the purpose of SPA</a>
    <a href="/page/url" onClick={goTo('/page/url')}>Here's a workaround  :)</a>
  </>
);

Conclusion

I’ve been fortunate to talk to SEO experts about this topic, and big tech media company developers about their experience using React to render content on the client side.

Unfortunately, all the folks I talked to said that they saw a huge dip in traffic. Either to long to index content, or parts of content not being indexed.

The part about long indexing times, is a bit iffy, since I witness my React friendly SEO page being indexed in 20 minutes. Perhaps Google search is getting smarter about JavaScript rendering.

Personally, I’ll stick to server side rendering because it’s easier, and less constraints or rules that I have to worry about.

You can see the React SEO friendly page here.

You can also see the Google query here.

I like to tweet about React and post helpful code snippets. Follow me there if you would like some too!