The Real-World Effect of NextJS on SEO

How converting my blog from vanilla React to NextJS affected SEO performance.

The Situation

For the past couple of years I’ve been publishing all my writing to my personal blog. A week or two after I’ve published on that site I’ll cross-publish to my Medium account using the import article tool.

By using Medium’s import tool the canonical link tag is set on the Medium version to point to my self-hosted blog. That’s basically the entire point of the import tool.

However, this dual-posting strategy creates an SEO tug-of-war between the two sites. Both have the same content but only one can show in search results. Which one shows up is, of course, chosen by Google.

Considering that more than 90% of all traffic to my posts is from organic search the winner of that battle will inherit virtually all traffic. This is one of my top performing posts. 98% of its views come from external referrals. Of which 75% of are Google.

The results of the SEO tug-of-war for the first 18 months of my blog looked like this.

Taking more than 95% of traffic, Medium was the undisputed winner.

After looking at these numbers I decided that I wanted to make my version of the blog SEO friendly. This would let me see the effect on traffic to both sites and it would give me insight to the value-add Medium brings to the table.

My Version One React Blog

The first version of my blog was written in plain React and served from an S3 bucket via Cloudfront.

Why would we care that it was written in React? React is a client-side rendering framework. Which means that Google won’t “see” it the same way it will see the Medium version. This is clear from the above results.

It turns out the SEO tug-of-war winner is not dependent on the canonical link tag. It is, in fact, page performance and the ability of Google to index the contents of a page that will determine which version appears in search results.

This is not to say that the blog wasn’t performant. It was reasonably optimized with lazy loading and image serving by Imgix. Page load speed was low 80’s and the site was scored as mobile friendly by Pagespeed .

This says one of three things:

Web crawlers do indeed give a notable penalty to SPA applications. Mediums page performance was so much better than my React pages that the weighting of the canonical link was overruled. Google completely ignores the canonical link tag.

I thought it was likely a combination of 1 & 2 but was not willing to rule out 3. After all, what interest does Google have in serving up the canonical page? Do they care where the traffic goes or do they care which experience is better for their users? The latter.

The Skinny On NextJS

If you are familiar with server-side-rendering or NextJS you can skip to the next section without missing anything.

NextJS serves one real purpose for single page applications (SPA), server-side-rendering (SSR). SSR takes your React and turns it into HTML on first request. This is opposed to a typical SPA site which sends down a big Javascript package to the browser. That Javascript will then generate the vast majority of the HTML the browser will display to the user. This difference in load techniques makes a world of difference on search rankings.

SEO bots crawl the web reading the HTML of each URL in their path. If that bot gets to a SPA page that is not SSR it’s going to be sent a big glob of Javascript instead of HTML. SEO bots don’t understand JS and they don’t always wait around for the JS to convert itself into HTML.¹ This means that these bots that decide what shows up on the first page of search results can’t read the page. If they can’t read the page, the page is not going to be served up by Google as the “best” option answer for a users search. This is where NextJS comes in.

By wrapping your SPA page into NextJS all queries to the URLs for your site will always result in a bot-friendly HTML page. You get the best of both worlds. You get to write SPA sites while retaining the SEO benefits of a traditional website architecture.

In fairness, NextJS does make development significantly more complicated — any attempt at SSR will. But if you need SSR benefits it’s arguably the best out-of-the-box option out there.

The SEO Results After Switching to NextJS

I’m a developer by day so I already knew about NextJS. An obvious choice³, it was only a matter of doing the rewrite. Over the course of a week I wrote and then deployed the new version.

On February 19, 2019 I deployed the rewritten NextJS blog and resubmitted all my URLs to Google Webmaster. This is what followed…

Within a week traffic to the Medium site had begun to fall off a cliff while traffic to PhilAndrews began to climb. This trend has continued until just recently.

But here’s where things get a little wonky and interesting. There is a major difference between my current page view counts and the page view counts I was getting on Medium.

Before the switch my Medium page views were increasing by about 5% month-over-month and I had eclipsed 11,000 views each of the two months prior to the switch.

Since I’ve switched to hosting my own site, according to Google Analytics, I’ve never eclipsed 6,000 page views in a month. And that number has been falling recently even though I’ve been putting out enough content that I would expect depreciating content traffic to be replaced by new content traffic. And even that logic goes against the normal compound interest you can typically expect from blogging. So I would expect things to stay at least level. But this is not the case.

This discrepancy in page view numbers leaves three questions to be answered.

1. Is Medium’s SEO power and distribution simply that much more powerful than going at it on your own?

Page view numbers would say it’s 45% more powerful.



On the surface this would make sense. They are a social platform where people can discover your work without having to search for it. However, my Medium traffic was already coming primarily from organic search and outside references.



Plus, even though Medium is a domain authority they’re an aggregator much like Twitter and Reddit. It’s not like going from writing about food on food.com to writing about food on your own site. In that case I would expect a major drop in SEO since you’d lose the topic authority of food.com in the food space.

2. Does Medium count views differently than Google?

Google: “Pageviews is the total number of pages viewed. Repeated views of a single page are counted” Medium: “Views are the number of visitors who clicked on a story’s page”

Unfortunately, I haven’t been able to think of any vectors from which to analyze this. Plus it seems unlikely that differing count methods would yield to a 5,000 view difference.

3. Does this answer the question of the effectiveness of the canonical link?

It’s seems clear to me that it’s completely ignored if the canonical page isn’t optimized. In this little experiment nothing changed except optimizing the canonical pages. Once they were optimized traffic began flowing to them.

Summary

I chose NextJS for my blog because I know React and it’s being actively developed by a company that’s making money. Which means it’ll be around for awhile.

With that being said, if follows that these results then aren’t specific to NextJS. You could do SSR yourself, Universal Angular, or any other service that turns your SPA page into HTML that web crawlers can index efficiently. The end result is that SSR definitely works for SEO. But it doesn’t mean the traffic from your self-hosted blog will be the same as you would get from writing on Medium.

To be candid, the title of this article is largely due to the fact that NextJS search trends have been rising and I believe that will continue to be the case. “The real-world effect of server-side-rendering on SEO” won’t do as well for organic search traffic. People will search for “NextJS SEO” more than “server side rendering SEO”.

¹ Google will let JS render itself into HTML but they won’t make any AJAX calls from your page. So if your page requires network requests to fetch content Google will never see the content that’s being fetched.