TL;DR

  • Search Engine Optimization (SEO) is a method used to place an URL or website at the top of a search engine's results.
  • SPA are non-friendly SEO websites because they are hard to crawl and a bit difficult to render content by GoogleBot.
  • We can get around the limits of SEO on SPA through some good practices like Server-side rendering, pre-rendering.

INTRODUCTION

Single Page Applications are transforming everyday customer experiences, from Twitter and LinkedIn to Netflix and Google Maps. More brands are developing SPAs in place of traditional websites, e-commerce storefronts, intranets, and online communities to keep up with the latest trend in digital experience.

However, if you're going to create a single-page application, you should consider its web visibility first. Because search engines and social network agents must interact with JavaScript instead of HTML, SPA SEO differs from that of a static page.

So before we talk about that, what is SEO ? And what are fundamental SEO ranking factors ? What is SPA ? And how can we make our SPA SEO-friendly?

What's SEO ?

The method of boosting the quality and quantity of online traffic to a website by increasing its exposure on search engines is known as Search Engine Optimization (SEO).

The primary goal of SEO is to help a web app rank higher in search engines (such as Google and Bing) when the target audience searches for information using a certain term. The majority of SEO efforts are geared toward making Google-friendly apps.

According to Backlinko, the first three websites in search engine results receive 75% of all user clicks, while pages on the second page and beyond receive only 0.78%. That is why digital firms are fighting for a spot on the first page of Google search results.

Fundamental SEO ranking factors:

Let's go over the different types of ranking factors before we get into the SEO ranking factors. Marketers commonly refer to on-page and off-page ranking factors, but there are three categories:

  • Off-page ranking factors: These are primarily backlinks that are measured by Google outside of your site.
  • On-page ranking factors: These are mostly concerned with the keywords you use and the informational value of your pages.
  • Technical ranking factors: These are likewise tracked on your site, but they focus on the site's general performance rather than specific pages.

1- Content quality (Off-page ranking factors):

Before you start building an app or a website, keep in mind that the primary SEO ranking factor is content quality. If your content is high-quality, distinctive, and valuable to your audience, it will begin to develop backlinks on its own. A page with a lot of links leading back to it tells Google that the page is valuable and comes from a reliable source.

2- Title and Meta tags (On-page ranking factors):

It's critical to include keywords in certain places on your website, such as the title and header tags, if you want to rank for them. These tags help search engines figure out what the page is about and index it effectively.

You can add different meta tags to your page Head:

  • Title Tag: This is the text that appears at the top of your browser's window. This content is considered the "title" of your page by search engines.
  • Meta Description Attribute: A brief description of the page.
  • Meta Keywords Attribute: A series of keywords you deem relevant to the page in question.

⚠️ Capital letters, numbers, special characters… should be avoided in your meta tags. Limited to 156 characters (including space)

3- Usability on mobile (Technical ranking factors):

When crawling websites, Google uses mobile-first indexing. This means that when a search engine evaluates a page, it preferentially uses the mobile version of the site.

Even if the desktop version of your site is excellent, if it isn't optimized for mobile, your search engine rating could suffer significantly. Always preview your web pages to ensure that they are usable on a variety of devices, not just desktops.

4- Performance (Technical ranking factors) :

Nobody likes a website that takes an eternity to load, and as Pingdom said, 38% of visitors bounce when your site takes five seconds to load. And search engines would agree if you asked them. That's why one of the most important aspects of technical SEO is having a website that loads swiftly and smoothly.

If your pages take too long to load, your bounce rate will likely soar, negatively impacting your rating. Page speed is a key ranking factor since users anticipate a pain-free surfing experience.

5- Security (HTTPS) (Technical ranking factors) :

A valid SSL certificate will demonstrate to both users and Googlebot that you are concerned about fighting malicious hackers.

What's SPA ?

A Single Page Application (SPA) is an app that works inside a browser and does not require page reloading during use. As Wikipedia defines it, it's a web application or website that interacts with users by dynamically rewriting the current web page with new data from the web server, rather than loading complete new pages as is the typical way. The idea is to make the website feel more like a native app with speedier transitions.

A page refresh is never required in a SPA; instead, the browser retrieves all necessary HTML, JavaScript, and CSS code with single page load, or the proper resources are dynamically loaded and appended to the page as needed, usually in reaction to user activities.

SEO issues with SPA  ?

Single Page Applications are commonly referred to as "non-friendly SEO websites" since they are difficult to crawl and render information for Googlebot. So, how does Googlebot function, and what are the concerns with SPA in terms of SEO?

1- Googlebot :

Bots are used by Google to rank web pages. These bots scan your site's pages for new content. When building a website, you can specify which pages should be crawled by including a list in the robots.txt file. You can also hide particular pages to avoid bot queries overloading your site.

The Googlebots then go on to indexing. A Googlebot evaluates the text of a web page to figure out what it's about during this procedure. The results of this process are saved in the Google index (a huge database with information about all web pages). Because web page indexing is automated, it's critical to arrange and format all material in a machine-readable format.

The serving and ranking processes are included in the third stage. When a user types something into Google, it searches the Google index for the most relevant results.

When we use React without server-side rendering, the crawler comes to a halt on the first page because there are no hyperlinks to follow. It sends the page to the indexer, who must then render it and extract the hyperlinks before adding them to the crawler's queue. The crawler will then move on to the next set of pages, but will come to a halt because all of the links are hidden until the JavaScript is rendered. As a result, it must wait for the indexer to return with a fresh set of URLs to crawl.

2- Performance :

Our SPA pages may have to wait in the render queue for a while, which can take a long time given the many pages produced and updated on the internet every day. Our JavaScript code must run quickly enough to fit inside Googlebot's render budget; otherwise, some elements of our pages may not render correctly, resulting in partial material being indexed. In the event of a rendering mistake, Googlebot's HTML may be broken or empty, preventing our full page from being indexed.

Small JavaScript code is vital for SEO and a quick initial page load. It applies to both client-side and server-side rendering SPAs. Lazy loading is an excellent solution to the problem of slow web apps.

3- Soft 404 error:

When a non-existent page (one that has been deleted/removed) displays a 'page not found' notice to anyone trying to access it, but does not send an HTTP 404 status code, it is referred to as a soft 404 error.

When we type a wrong URL into a Single Website Application in SPA, the page appears to return a 200 code when it should have returned a 404. For example, the website https://example.com/bad-url appears to be a 404, but instead returns 200:

The problem relates to the way SPA works. Meaning that there is no such thing as a 404 in a Single Page Application because it is all one application, and the "PAGE NOT FOUND" component is only a component that gets hidden or shown depending on the routing/mapping of the pages. When the app doesn't have any routing to a non-existing URL, the component that informs users that the page doesn't exist is displayed.

When a user asks for a nonexistent URL on your website, we should display an individual error page informing them that the requested URL does not exist for SEO purposes. We should also ensure that the server delivers the correct HTTP status code 404, so that search engines are aware that a URL is no longer available and, after a period, the search engine delete that URL from the index.

If a 404 page produces an incorrect HTTP status code, such as 200, the URL may appear in search results. The result is as follows:

⚠️ In case you use a Server like Apache you can use an .htaccess file to return 404 error by adding a custom html 404-page.html error, and redirect all the wrong pages to /page_not_found  in your router.

Redirect 404 /page_not_found
ErrorDocument 404 /custom-404.html

4- 301 and 302 Redirection :

In the case of domain migration, Google suggests employing server-side, permanent 301 or 302 redirections. Permanent redirects can protect the page rank while also notifying search engines that the page is permanent, allowing them to crawl and index new sites as soon as possible and rank them too. Also, search engines must decide whether to preserve the old page or replace it with the one located at the new address. Search engines may become confused if the wrong form of redirect is used, resulting in a loss of traffic.

So, because it's all one application, we can't return a 301 or 302 HTTP status even if we use Redirect.

⚠️ In case you use a Server like Apache you can you .htaccess file to do a 301 or 302 redirect.

Redirect 301 /old-page.html /new-page.html

Best practices for SPA SEO:

Now that you're aware of the possible downsides of single-page applications, let's move on to some SPA SEO best practices.

1- React-Helmet:

React Helmet is a library that helps you by adding meta tags to your React components so your site gives more valuable information to the crawlers.

  • Step 1 - Install react-helmet using yarn or npm
yarn add react-helmet
//or
npm install react-helmet

  • Step 2 - use react-helmet in your component

Now we need to modify the component to start using Helmet in a way that we can use title tags and meta tags:

import { Helmet } from 'react-helmet';

function App() {
  return (
    <div>
    	<Helmet>‍
        	<title>SEO DEMO</title>‍
        	<meta name="description" content="seo demo" />
    	</Helmet>
      	<h1>SEO DEMO</h1>
    </div>
  );
}

export default App;

So now you can see in the Head of your page:

<head>‍
  <title>SEO DEMO</title>‍
  <meta name="description" content="seo demo">‍
‍</head>

2- Auto generate sitemap :

A sitemap is a virtual map that provides Search Engines with the information they need to determine which pages on a website are significant. We'll learn how to do it automatically.

  • Step 1 - Install react-router-sitemap using yarn or npm
yarn add react-router-sitemap
//or
npm install react-router-sitemap

  • Step 2 - Create a sitemap-routes.js file:

If you try to run react-router-sitemap on an existing Routes.js file, you'll get all kinds of Babel errors. Instead, follow these instructions. I duplicated the routes file solely to build a sitemap. Here's an example of a sitemap-routes.js file:

import React from 'react';
import { Route } from 'react-router';

export default (
  <Route>
    <Route path='/' />
    <Route path='/url-1' />
    <Route path='/url-2' />
  </Route>
);

⚠️ You should add your new route manually to sitemap-routes.js if you need it to be in the generated sitemap.

  • Step 3 - Create your sitemap-generator.js:

This file will produce your sitemap.xml file by doing the heavy lifting. Here's a simple sitemap-generator.js file to get you started.

  // you will need this deps to use react-router-sitemap
  require('babel-register')({
    presets: ['es2015', 'react'],
  });
  
  const router = require('./sitemap-routes').default;
  const Sitemap = require('react-router-sitemap').default;
  
  new Sitemap(router)
  .build("https://www.example.com/")
  .save("./public/sitemap.xml");

Make sure you change your paths and domain name accordingly. sitemap.xml should be typically located in the root directory of the domain.

  • Step 4 - Running your sitemap-generator.js file

Install the following dev dependencies:

yarn add babel-preset-es2015 babel-preset-react babel-register --dev
// or 
npm install --dev babel-preset-es2015 babel-preset-react babel-register

Now add a script in your package.json:

...
"scripts": {
    ...
    "generate-sitemap": "node path/to/your/sitemap-generator.js"
  }
...

Now run the command bellow to generate a sitemap:

yarn generate-sitemap
// or 
npm run generate-sitemap

Your sitemap.xml file should be generated inside your public folder.

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="<http://www.sitemaps.org/schemas/sitemap/0.9>" xmlns:news="<http://www.google.com/schemas/sitemap-news/0.9>" xmlns:xhtml="<http://www.w3.org/1999/xhtml>" xmlns:mobile="<http://www.google.com/schemas/sitemap-mobile/1.0>" xmlns:image="<http://www.google.com/schemas/sitemap-image/1.1>" xmlns:video="<http://www.google.com/schemas/sitemap-video/1.1>">
<url> <loc><https://www.seo.example.com/></loc> </url>
<url> <loc><https://www.seo.example.com/></loc> </url>
<url> <loc><https://www.seo.example.com/url-1></loc> </url>
<url> <loc><https://www.seo.example.com/url-2></loc> </url>
</urlset>

  • Step 5 - Adding sitemap generation to your deployment workflow

You could for example automatically generate sitemap.xml whenever you deploy in your predeploy step in your package.json:

...
"scripts": {
    ...
   "predeploy": "yarn generate-sitemap"
  }
...

3- Open Graph:

Open Graph is a protocol that allows us to control what content is shown when our websites are shared on Facebook or any other social media platform.

We can virtually control what people see when they share our website by utilizing Open Graph tags. We have a far better chance of getting readers interested enough to click your website if you include a relevant image, headline, and content.

  • Open Graph issue with SPA:

If we try to add Open Graph meta tags to our SPA using react-helmet :

import { Helmet } from "react-helmet";

function App() {
  return (
    <div>
      <Helmet>
        ‍<title>SEO DEMO</title>‍
        <meta name="description" content="seo demo" />
        <meta property="og:title" content="SEO DEMO" />
        <meta property="og:description" content="seo demo" />
        <meta property="og:url" content="" />
        <meta property="og:site_name" content="SEO DEMO" />
        <meta
          property="og:image"
          content="<https://d57439wlqx3vo.cloudfront.net/iblock/bc0/bc0f0fade6094e32d26afe9ee426bf47/a1d39b9944184055866844a5d88fdec3.png>"
        />
      </Helmet>
      <h1>SEO DEMO</h1>
    </div>
  );
}

export default App;`

and then check our OG tags using OpenGraph.xyz, we can see that even if we added the right open graph meta tags to our react-helmet, we couldn't see it when we shared our page in a post. :

This is because when we shared our URL in a post, JavaScript hadn't yet been interpreted, and react-helmet couldn't add our meta tags to the head of index.html.

So to resolve this problem, we should put directly our open graph in the public/index.html:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
    <title>SEO DEMO</title>‍
        <meta name="description" content="seo demo" />
        <meta property="og:title" content="SEO DEMO" />
        <meta property="og:description" content="seo demo" />
        <meta property="og:url" content="" />
        <meta property="og:site_name" content="SEO DEMO" />
        <meta
          property="og:image"
          content="<https://d57439wlqx3vo.cloudfront.net/iblock/bc0/bc0f0fade6094e32d26afe9ee426bf47/a1d39b9944184055866844a5d88fdec3.png>"
        />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="theme-color" content="#000000" />
    <meta
      name="description"
      content="Web site created using create-react-app"
    />
    <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
    <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
    
    <title>React App</title>
  </head>
  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
  </body>
</html>

Now if we try again using OpenGraph.xyz to test our OG tag, it works 🎉:

⚠️ We can't add OG tags to multiple pages in our SPA when we use client-side rendering, so we will see the same tags added to the index.html for every page in our application.

How to make our SPA SEO-friendly:

All the constraints we've discussed so far can be overcome. Here are some best practices for dealing with React and SEO issues.

1- Server-side rendering:

The term "server-side rendering" refers to the process of doing the browser's work on the server. The server responds to connection requests by returning the complete page content as a readable HTML response. Even if the JavaScript code is not run, readable material shows, but the page lacks the dynamics that the JavaScript scripts give. The JavaScript functions then begin to run, and the page begins to take advantage of the benefits provided by current UI libraries.

Browsers and Google bots obtain HTML files with all the content when server-side rendering is used. Google bots can properly index the page and give it a higher ranking.

2- Pre-rendering:

Pre-rendering is a typical technique for optimizing single- and multi-page web apps for search engines.

Pre-rendering is used when search bots are unable to render your sites correctly. In these cases, you can employ pre-renderers, which are special programs that intercept requests to your website and send a cached static HTML version of your website if the request is from a bot. The typical page is loaded if the request comes from a user. We can use paid services like Prerender.

⚠️ Pre-rendering isn’t suitable for pages that display frequently changing data.

Conclusion:

We discussed what is SEO and the main fundamental factors to have good ranking in search engines. After that we saw what is SPA, the issues with SEO and some good practices to boost our application, we came to the conclusion that there are many limitations when using client-side rendering.

Having worked on several React projects and dealing with their SEO optimization, we are convinced that server-side rendering can help us to solve all the limitations. As a recommendation, we can use Next.js, a popular framework built on top of React that offers many features allowing even the most fully loaded SPAs to render without a hitch on the server.