{"id":138897,"date":"2022-03-01T02:00:14","date_gmt":"2022-03-01T07:00:14","guid":{"rendered":"https:\/\/ahrefs.com\/blog\/?p=138897"},"modified":"2024-06-16T17:16:04","modified_gmt":"2024-06-16T22:16:04","slug":"react-seo","status":"publish","type":"post","link":"https:\/\/ahrefs.com\/blog\/react-seo\/","title":{"rendered":"React SEO: Best Practices to Make It SEO-Friendly"},"content":{"rendered":"<div class=\"intro-txt\">The increasing prevalence of <a href=\"https:\/\/reactjs.org\">React<\/a>&nbsp;in modern web development cannot be ignored.<\/div>\n<p>React and other similar libraries (like <a href=\"https:\/\/vuejs.org\">Vue.js<\/a>) are becoming the de&nbsp;facto choice for larger businesses that require complex development where a more simplistic approach&nbsp;(like using a WordPress theme)&nbsp;won\u2019t satisfy the requirements.<\/p>\n<p>Despite that, SEOs did not initially embrace libraries like React&nbsp;due to search engines struggling to effectively render JavaScript, with&nbsp;content available <a href=\"https:\/\/support.google.com\/surveys\/answer\/6172725?hl=en\">within the HTML source<\/a>&nbsp;being the preference.<\/p>\n<p>However, developments in both how Google and React can render JavaScript have&nbsp;simplified these complexities, resulting in SEO no longer being the blocker for using&nbsp;React.<\/p>\n<p>Still, some complexities remain, which I\u2019ll run through in&nbsp;this guide.<\/p>\n<p>On that note, here\u2019s what we\u2019ll&nbsp;cover:<\/p>\n<ul>\n<li><a href=\"#1-what-is-react\">What React&nbsp;is<\/a><\/li>\n<li><a href=\"#2-rendering-with-react\">Rendering with&nbsp;React<\/a><\/li>\n<li><a href=\"#3-how-google-processes-pages\">How Google processes pages<\/a><\/li>\n<li><a href=\"#4-common-seo-issues\">Common SEO issues with&nbsp;React<\/a><\/li>\n<\/ul>\n<div class=\"post-nav-link clearfix\" id=\"section1\"><a class=\"subhead-anchor\" data-tip=\"tooltip__copielink\" rel=\"#section1\"><svg width=\"19\" height=\"19\" viewBox=\"0 0 14 14\" style><g fill=\"none\" fill-rule=\"evenodd\"><path d=\"M0 0h14v14H0z\" \/><path d=\"M7.45 9.887l-1.62 1.621c-.92.92-2.418.92-3.338 0a2.364 2.364 0 0 1 0-3.339l1.62-1.62-1.273-1.272-1.62 1.62a4.161 4.161 0 1 0 5.885 5.884l1.62-1.62L7.45 9.886zM5.527 5.135L7.17 3.492c.92-.92 2.418-.92 3.339 0 .92.92.92 2.418 0 3.339L8.866 8.473l1.272 1.273 1.644-1.643A4.161 4.161 0 1 0 5.897 2.22L4.254 3.863l1.272 1.272zm-.66 3.998a.749.749 0 0 1 0-1.06l2.208-2.206a.749.749 0 1 1 1.06 1.06L5.928 9.133a.75.75 0 0 1-1.061 0z\" style \/><\/g><\/svg><\/a><div class=\"link-text\" data-anchor=\"But first, what is React?\" data-section=\"1-what-is-react\">\n<h2>But first, what is&nbsp;React?<\/h2>\n<\/div><\/div>\n<p>React is an open-source JavaScript library developed by Meta (formerly Facebook) for building web and mobile applications. The main features of React are that it&nbsp;is&nbsp;declarative, is component-based, and allows easier manipulation <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/Document_Object_Model\/Introduction\">of the DOM<\/a>.<\/p>\n<p>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 <a href=\"https:\/\/mui.com\">component libraries like MUI<\/a>&nbsp;or <a href=\"https:\/\/tailwindui.com\">Tailwind UI<\/a>.<\/p>\n<p>If you want the full lowdown on why developers love React, start&nbsp;here:<\/p>\n<ul>\n<li><a href=\"https:\/\/ui.dev\/imperative-vs-declarative-programming\">Imperative vs.&nbsp;Declarative Programming<\/a><\/li>\n<li><a href=\"https:\/\/www.geeksforgeeks.org\/reactjs-components\/\">React components<\/a><\/li>\n<\/ul>\n<div class=\"post-nav-link clearfix\" id=\"section1\"><a class=\"subhead-anchor\" data-tip=\"tooltip__copielink\" rel=\"#section1\"><svg width=\"19\" height=\"19\" viewBox=\"0 0 14 14\" style><g fill=\"none\" fill-rule=\"evenodd\"><path d=\"M0 0h14v14H0z\" \/><path d=\"M7.45 9.887l-1.62 1.621c-.92.92-2.418.92-3.338 0a2.364 2.364 0 0 1 0-3.339l1.62-1.62-1.273-1.272-1.62 1.62a4.161 4.161 0 1 0 5.885 5.884l1.62-1.62L7.45 9.886zM5.527 5.135L7.17 3.492c.92-.92 2.418-.92 3.339 0 .92.92.92 2.418 0 3.339L8.866 8.473l1.272 1.273 1.644-1.643A4.161 4.161 0 1 0 5.897 2.22L4.254 3.863l1.272 1.272zm-.66 3.998a.749.749 0 0 1 0-1.06l2.208-2.206a.749.749 0 1 1 1.06 1.06L5.928 9.133a.75.75 0 0 1-1.061 0z\" style \/><\/g><\/svg><\/a><div class=\"link-text\" data-anchor=\"Rendering with React, a short history\" data-section=\"2-rendering-with-react\">\n<h2>Rendering with React, a short history<\/h2>\n<\/div><\/div>\n<p>React implements an <a href=\"https:\/\/developers.google.com\/web\/fundamentals\/architecture\/app-shell\">App Shell Model<\/a>, meaning the vast majority of content, if not all, will be Client-side Rendered (CSR) by default.<\/p>\n<p>CSR means the HTML primarily contains the React JS library rather than the server sending&nbsp;the entire page\u2019s contents within the initial HTTP response from the server (the HTML source).<\/p>\n<p>It will also include miscellaneous JavaScript containing <a href=\"https:\/\/www.pluralsight.com\/guides\/load-and-render-json-data-into-react-components\">JSON data<\/a>&nbsp;or links to JS files that contain&nbsp;React components. You can quickly tell a site is client-side rendered by checking the HTML source. To do that,&nbsp;right-click and select \u201cView Page Source\u201d&nbsp;(or CTRL + U\/CMD +&nbsp;U).<\/p>\n<div style=\"width: 1448px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/ahrefs.com\/blog\/wp-content\/uploads\/2022\/02\/1-netflix-html.png\" alt=\"Netflix's homepage source HTML\" width=\"1438\" height=\"414\"><p class=\"wp-caption-text\">A screenshot of the netlfix.com homepage source HTML.<\/p><\/div>\n<p>If you don\u2019t see many lines of HTML there, the application is likely client-side rendering.<\/p>\n<p>However, when you inspect the element by right-clicking and selecting \u201cInspect element\u201d&nbsp;(or F12\/CMD + \u2325&nbsp;+ I), you\u2019ll see the DOM generated by the browser (where the browser has rendered JavaScript).<\/p>\n<p>The result is you\u2019ll then see the site has&nbsp;a lot of&nbsp;HTML:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-138892\" src=\"https:\/\/ahrefs.com\/blog\/wp-content\/uploads\/2022\/02\/2-lots-of-html.jpg\" alt=\"Lots of HTML\" width=\"1600\" height=\"768\" srcset=\"https:\/\/ahrefs.com\/blog\/wp-content\/uploads\/2022\/02\/2-lots-of-html.jpg 1600w, https:\/\/ahrefs.com\/blog\/wp-content\/uploads\/2022\/02\/2-lots-of-html-680x326.jpg 680w, https:\/\/ahrefs.com\/blog\/wp-content\/uploads\/2022\/02\/2-lots-of-html-768x369.jpg 768w, https:\/\/ahrefs.com\/blog\/wp-content\/uploads\/2022\/02\/2-lots-of-html-1536x737.jpg 1536w\" sizes=\"auto, (max-width: 1600px) 100vw, 1600px\"><\/p>\n<div style=\"text-align: center;\"><\/div>\n<p>Note the appMountPoint ID on&nbsp;the first &lt;div&gt;. You\u2019ll commonly see an element like that on a <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Glossary\/SPA\">single-page application (SPA)<\/a>, so a library like React knows where it should inject HTML. <a href=\"https:\/\/www.wappalyzer.com\">Technology detection tools, e.g., Wappalyzer<\/a>,&nbsp;are also great at detecting the library.<\/p>\n<div class=\"editor-note\"><div class=\"editor-title\">Editor\u2019s Note<\/div><div class=\"editor-content\">\n<p>Ahrefs\u2019 <a href=\"https:\/\/ahrefs.com\/site-audit\">Site Audit<\/a>&nbsp;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.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-138886\" src=\"https:\/\/ahrefs.com\/blog\/wp-content\/uploads\/2022\/02\/3-raw-and-rendered-html.gif\" alt=\"Gif showing Site Audit saves both Raw HTML and Rendered HTML\" width=\"800\" height=\"516\"><\/p>\n<div style=\"text-align: center;\"><\/div>\n<p>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 &lt;h1&gt;&nbsp;tag.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-138887\" src=\"https:\/\/ahrefs.com\/blog\/wp-content\/uploads\/2022\/02\/4-h1-tag.gif\" alt=\"Gif showing site is client-side rendering key page content\" width=\"800\" height=\"550\"><\/p>\n<div style=\"text-align: center;\"><\/div>\n<\/div><div class=\"editor-info clearfix\"><div class=\"editor-photo\"><img decoding=\"async\" alt=\"Joshua Hardwick\" src=\"https:\/\/ahrefs.com\/blog\/wp-content\/uploads\/2017\/09\/me.jpg\"><\/div><div class=\"extra-box\"><div class=\"editor\">Joshua Hardwick<\/div><div class=\"editor-job\">Head of Content<\/div><\/div><\/div><\/div>\n<p>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\u2014called Server-side Rendering (SSR).<\/p>\n<div style=\"width: 1610px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/ahrefs.com\/blog\/wp-content\/uploads\/2022\/02\/5-ssr.png\" alt=\"Flowchart showing the SSR process \" width=\"1600\" height=\"1057\"><p class=\"wp-caption-text\">The above shows the server rendering JavaScript into HTML with React (more on that shortly). The concept is the same for sites built with PHP (like WordPress). It\u2019s just PHP being turned into HTML rather than JavaScript.<\/p><\/div>\n<p>Before&nbsp;SSR, developers kept it even simpler.<\/p>\n<p>They would create static HTML documents that didn\u2019t change, host them on a server,&nbsp;and then send&nbsp;them&nbsp;immediately. The server didn\u2019t need to render anything,&nbsp;and the browser often had very little to render.<\/p>\n<p>SPAs (including those using React) are now coming full circle&nbsp;back to this static approach. They\u2019re now pre-rendering JavaScript into HTML&nbsp;before a browser requests&nbsp;the URL. This approach is called Static Site Generation (SSG), also known as Static Rendering.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-138889\" src=\"https:\/\/ahrefs.com\/blog\/wp-content\/uploads\/2022\/02\/6-ssg.png\" alt=\"Two flowcharts showing the SSG process \" width=\"1467\" height=\"1600\" srcset=\"https:\/\/ahrefs.com\/blog\/wp-content\/uploads\/2022\/02\/6-ssg.png 1467w, https:\/\/ahrefs.com\/blog\/wp-content\/uploads\/2022\/02\/6-ssg-390x425.png 390w, https:\/\/ahrefs.com\/blog\/wp-content\/uploads\/2022\/02\/6-ssg-768x838.png 768w, https:\/\/ahrefs.com\/blog\/wp-content\/uploads\/2022\/02\/6-ssg-1408x1536.png 1408w\" sizes=\"auto, (max-width: 1467px) 100vw, 1467px\"><\/p>\n<div style=\"text-align: center;\"><\/div>\n<p>In practice, SSR&nbsp;and SSG are&nbsp;similar.<\/p>\n<p>The key difference is&nbsp;that rendering happens with SSR when a browser requests a URL&nbsp;versus a framework pre-rendering content at build time with SSG (when developers&nbsp;deploy&nbsp;new code or&nbsp;a web admin&nbsp;changes the site\u2019s content).<\/p>\n<p>SSR can be more dynamic but slower due to additional latency while the server renders the content before sending it to&nbsp;the user\u2019s&nbsp;browser.<\/p>\n<p>SSG is faster, as the content has already been rendered, meaning it can be served to the user immediately (meaning a quicker&nbsp;TTFB).<\/p>\n<div class=\"post-nav-link clearfix\" id=\"section1\"><a class=\"subhead-anchor\" data-tip=\"tooltip__copielink\" rel=\"#section1\"><svg width=\"19\" height=\"19\" viewBox=\"0 0 14 14\" style><g fill=\"none\" fill-rule=\"evenodd\"><path d=\"M0 0h14v14H0z\" \/><path d=\"M7.45 9.887l-1.62 1.621c-.92.92-2.418.92-3.338 0a2.364 2.364 0 0 1 0-3.339l1.62-1.62-1.273-1.272-1.62 1.62a4.161 4.161 0 1 0 5.885 5.884l1.62-1.62L7.45 9.886zM5.527 5.135L7.17 3.492c.92-.92 2.418-.92 3.339 0 .92.92.92 2.418 0 3.339L8.866 8.473l1.272 1.273 1.644-1.643A4.161 4.161 0 1 0 5.897 2.22L4.254 3.863l1.272 1.272zm-.66 3.998a.749.749 0 0 1 0-1.06l2.208-2.206a.749.749 0 1 1 1.06 1.06L5.928 9.133a.75.75 0 0 1-1.061 0z\" style \/><\/g><\/svg><\/a><div class=\"link-text\" data-anchor=\"How Google processes pages\" data-section=\"3-how-google-processes-pages\">\n<h2>How Google processes pages<\/h2>\n<\/div><\/div>\n<p>To understand why React\u2019s default client-side rendering approach&nbsp;causes SEO issues, you first need to know&nbsp;how Google crawls, processes,&nbsp;and indexes pages.<\/p>\n<p>We can summarize the basics&nbsp;of how this works&nbsp;in&nbsp;the below&nbsp;steps:<\/p>\n<ol>\n<li><strong>Crawling<\/strong>&nbsp;\u2013&nbsp;<a href=\"https:\/\/ahrefs.com\/blog\/googlebot\/\">Googlebot<\/a>&nbsp;sends&nbsp;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,&nbsp;and more.<\/li>\n<li><strong>Processing<\/strong>&nbsp;\u2013&nbsp;This includes adding URLs to the crawl queue found within &lt;a href&gt; links within the HTML. It also includes queuing resource URLs (CSS\/JS) found within <a href=\"https:\/\/www.w3schools.com\/tags\/tag_link.asp\">&lt;link&gt;<\/a>&nbsp;tags or images within <a href=\"https:\/\/www.w3schools.com\/tags\/tag_img.asp\">&lt;img src&gt;<\/a>&nbsp;tags. If Googlebot finds a noindex tag at this stage, the process stops,&nbsp;Googlebot won\u2019t render the content, and Caffeine (Google\u2019s indexer) won\u2019t index&nbsp;it.<\/li>\n<li><strong>Rendering<\/strong>&nbsp;\u2013&nbsp;Googlebot executes JavaScript code with a <a href=\"https:\/\/chromium.googlesource.com\/chromium\/src\/+\/lkgr\/headless\/README.md\">headless Chromium browser<\/a>&nbsp;to find additional content within the DOM, but not the HTML source. It does this for all HTML&nbsp;URLs.<\/li>\n<li><strong>Indexing<\/strong>&nbsp;\u2013&nbsp;Caffeine takes the information from Googlebot, normalizes&nbsp;it (fixes broken HTML), and then tries to make sense of it all, precomputing some ranking signals ready for serving within a search result.<\/li>\n<\/ol>\n<div style=\"text-align: center;\"><img decoding=\"async\" src=\"https:\/\/ahrefs.com\/blog\/wp-content\/uploads\/2022\/02\/7-google-crawls-processes-indexes-pages.png\" alt=\"Flowchart showing how Google crawls, processes, and indexes pages\"><\/div>\n<div class=\"sidenote\"><div class=\"sidenote-title\">Sidenote.<\/div> If you want to learn more about this process, Google has a <a href=\"https:\/\/developers.google.com\/search\/docs\/advanced\/javascript\/javascript-seo-basics\">great explanation<\/a>. Patrick&nbsp;Stox also has an article&nbsp;explaining&nbsp;the critical&nbsp;need-to-know&nbsp;<a href=\"https:\/\/ahrefs.com\/blog\/javascript-seo\/\">JavaScript SEO facts<\/a>.<\/div>\n<p>Historically, issues with React and other JS libraries have been due to Google not handling the rendering step&nbsp;well.<\/p>\n<p>Some examples include:<\/p>\n<ul>\n<li><strong>Not rendering JavaScript<\/strong>&nbsp;\u2013&nbsp;It\u2019s an older issue, but Google only started <a href=\"https:\/\/searchengineland.com\/google-now-crawling-and-indexing-flash-content-14299\">rendering JavaScript in a limited way in 2008<\/a>. However,&nbsp;it&nbsp;was&nbsp;still reliant on a crawling scheme for JavaScript sites created in 2009. (Google&nbsp;<a href=\"https:\/\/developers.google.com\/search\/blog\/2015\/10\/deprecating-our-ajax-crawling-scheme\">has<\/a><a href=\"https:\/\/developers.google.com\/search\/blog\/2015\/10\/deprecating-our-ajax-crawling-scheme\">&nbsp;since deprecated<\/a>&nbsp;the scheme.)<\/li>\n<li><strong>The rendering engine (Chromium) being out of date<\/strong>&nbsp;\u2013&nbsp;This resulted in a <a href=\"https:\/\/www.deepcrawl.com\/blog\/news\/what-version-of-chrome-is-google-actually-using-for-rendering\/\">lack of support for the latest browser and JavaScript features<\/a>. If you used a JavaScript feature that Googlebot didn\u2019t support, your page might&nbsp;not render correctly, which could negatively impact your content\u2019s indexing.<\/li>\n<li><strong>Google had a r<\/strong><strong>endering delay <\/strong>\u2013&nbsp;In some cases, this could <a href=\"https:\/\/twitter.com\/Paul_Kinlan\/status\/1040147543345098752\">mean a delay of up to a few weeks<\/a>, slowing down the time for changes to the content to reach the indexing stage.&nbsp;This would have ruled out relying on Google to render content for most&nbsp;sites.<\/li>\n<\/ul>\n<p>Thankfully, Google has now resolved most of these issues. <a href=\"https:\/\/developers.google.com\/search\/blog\/2019\/05\/the-new-evergreen-googlebot\">Googlebot is now evergreen<\/a>, meaning it always supports the latest features of Chromium.<\/p>\n<p>In addition, the rendering delay is now five&nbsp;seconds, as announced by Martin Splitt at the Chrome Developer Summit in November 2019:<\/p>\n<blockquote class=\"small\"><div class=\"quote-content\">Last year Tom Greenaway&nbsp;and I were on this stage and telling you, \u2018Well, you know, it can take up to a week, we are very sorry for this.\u2019&nbsp;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 \u2013 on median \u2013 it\u2019s five seconds!\u201d<\/div><\/blockquote>\n<p>This all sounds positive. But is client-side rendering and leaving Googlebot to render content the right strategy?<\/p>\n<p>The answer is most likely still&nbsp;no.<\/p>\n<div class=\"post-nav-link clearfix\" id=\"section1\"><a class=\"subhead-anchor\" data-tip=\"tooltip__copielink\" rel=\"#section1\"><svg width=\"19\" height=\"19\" viewBox=\"0 0 14 14\" style><g fill=\"none\" fill-rule=\"evenodd\"><path d=\"M0 0h14v14H0z\" \/><path d=\"M7.45 9.887l-1.62 1.621c-.92.92-2.418.92-3.338 0a2.364 2.364 0 0 1 0-3.339l1.62-1.62-1.273-1.272-1.62 1.62a4.161 4.161 0 1 0 5.885 5.884l1.62-1.62L7.45 9.886zM5.527 5.135L7.17 3.492c.92-.92 2.418-.92 3.339 0 .92.92.92 2.418 0 3.339L8.866 8.473l1.272 1.273 1.644-1.643A4.161 4.161 0 1 0 5.897 2.22L4.254 3.863l1.272 1.272zm-.66 3.998a.749.749 0 0 1 0-1.06l2.208-2.206a.749.749 0 1 1 1.06 1.06L5.928 9.133a.75.75 0 0 1-1.061 0z\" style \/><\/g><\/svg><\/a><div class=\"link-text\" data-anchor=\"Common SEO issues with React\" data-section=\"4-common-seo-issues\">\n<h2>Common SEO issues with&nbsp;React<\/h2>\n<\/div><\/div>\n<p>In the past five years, Google has&nbsp;innovated its handling of JavaScript content, but entirely&nbsp;client-side rendered sites introduce other issues that you need to consider.<\/p>\n<p>It\u2019s important to note&nbsp;that&nbsp;<strong>you can overcome all issues with React and SEO<\/strong><strong>.<\/strong><\/p>\n<p>React JS is a development tool. React&nbsp;is no different from any other tool within a development stack,&nbsp;whether that\u2019s a WordPress plugin or the CDN you choose.&nbsp;How you configure it will decide whether it detracts or enhances SEO.<\/p>\n<p>Ultimately, <strong>React is good for SEO, as it improves user experience<\/strong>. You just need to make sure you consider the following common issues.<\/p>\n<h3>1. Pick the right rendering strategy<\/h3>\n<p>The most significant&nbsp;issue you\u2019ll need to tackle with React is how&nbsp;it renders content.<\/p>\n<p>As mentioned, Google is great at rendering JavaScript nowadays.&nbsp;But unfortunately, that isn\u2019t the case with other search engines. <a href=\"https:\/\/blogs.bing.com\/webmaster\/october-2019\/The-new-evergreen-Bingbot-simplifying-SEO-by-leveraging-Microsoft-Edge\/\">Bing has some support for JavaScript rendering<\/a>, although its efficiency&nbsp;is unknown. Other search engines like Baidu, Yandex,&nbsp;and others offer limited support.<\/p>\n<div class=\"sidenote\"><div class=\"sidenote-title\">Sidenote.<\/div> This limitation doesn\u2019t only impact search engines. Apart from site auditors, SEO tools that crawl the web and provide critical data on elements like a site\u2019s backlinks <strong>do not render JavaScript<\/strong>.&nbsp;This can have a <strong>significant impact<\/strong>&nbsp;on the quality of data they provide. The only exception is Ahrefs, which has been <a href=\"https:\/\/ahrefs.com\/blog\/crawling-javascript\/\">rendering JavaScript across the web since 2017<\/a>&nbsp;and currently renders <strong>over 200 million pages per day<\/strong>.<\/div>\n<p>Introducing this unknown builds a good case for opting for a server-side rendered solution to ensure that all crawlers can see the site\u2019s content.<\/p>\n<p>In addition, rendering content on&nbsp;the server has another crucial&nbsp;benefit:&nbsp;<strong>load times<\/strong>.<\/p>\n<h4>Load times<\/h4>\n<p><a href=\"https:\/\/www.speedcurve.com\/blog\/javascript-dominates-browser-cpu\/\">Rendering JavaScript is intensive on the CPU<\/a>; this makes large libraries like React slower to load and become interactive for users. You\u2019ll generally see <a href=\"https:\/\/ahrefs.com\/blog\/core-web-vitals\/\">Core Web Vitals<\/a>, such as&nbsp;Time to&nbsp;Interactive (TTI), being much higher for SPAs\u2014especially on mobile,&nbsp;<a href=\"https:\/\/www.similarweb.com\/platforms\/\">the primary way users consume web content<\/a>.<\/p>\n<div style=\"width: 1610px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/ahrefs.com\/blog\/wp-content\/uploads\/2022\/02\/8-react-app-utilizes-csr.jpg\" alt=\"Overview of metrics' performance, including FCP, LCP, etc\" width=\"1600\" height=\"462\"><p class=\"wp-caption-text\">An example React application that utilizes client-side rendering.<\/p><\/div>\n<p>However, after the initial render by the browser, subsequent load times tend to be quicker due to the following:<\/p>\n<ul>\n<li>Client-side rendering is not causing a full-page refresh, meaning the library only needs loading once.<\/li>\n<li><a href=\"https:\/\/reactjs.org\/docs\/reconciliation.html\">React\u2019s <\/a><a href=\"https:\/\/reactjs.org\/docs\/reconciliation.html\">\u201c<\/a><a href=\"https:\/\/reactjs.org\/docs\/reconciliation.html\">diffing<\/a><a href=\"https:\/\/reactjs.org\/docs\/reconciliation.html\">\u201d<\/a><a href=\"https:\/\/reactjs.org\/docs\/reconciliation.html\">&nbsp;algorithm<\/a>&nbsp;only changes&nbsp;HTML in the DOM that has changed state\u2014resulting in the browser <a href=\"https:\/\/medium.com\/@gethylgeorge\/how-virtual-dom-and-diffing-works-in-react-6fc805f9f84e\">only re-rendering content that has changed<\/a>.<\/li>\n<\/ul>\n<p>Depending on the number of pages viewed per visit, this can result in field data being positive overall.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-138894\" src=\"https:\/\/ahrefs.com\/blog\/wp-content\/uploads\/2022\/02\/9-positive-field-data.png\" alt=\"Four bar graphs showing positive field data of FCP, LCP, FID, and CLS\" width=\"1600\" height=\"393\" srcset=\"https:\/\/ahrefs.com\/blog\/wp-content\/uploads\/2022\/02\/9-positive-field-data.png 1600w, https:\/\/ahrefs.com\/blog\/wp-content\/uploads\/2022\/02\/9-positive-field-data-680x167.png 680w, https:\/\/ahrefs.com\/blog\/wp-content\/uploads\/2022\/02\/9-positive-field-data-768x189.png 768w, https:\/\/ahrefs.com\/blog\/wp-content\/uploads\/2022\/02\/9-positive-field-data-1536x377.png 1536w\" sizes=\"auto, (max-width: 1600px) 100vw, 1600px\"><\/p>\n<div style=\"text-align: center;\"><\/div>\n<p>However, if your site has a low number of pages viewed per visit, you\u2019ll struggle to get positive field data for all Core Web Vitals.<\/p>\n<h4>Solution<\/h4>\n<p>The best option is to opt for SSR or SSG mainly due&nbsp;to:<\/p>\n<ul>\n<li>Faster initial renders.<\/li>\n<li>Not having to rely on search engine crawlers to render content.<\/li>\n<li>Improvements in TTI due to less JavaScript code for the browser to parse and render before becoming interactive.<\/li>\n<\/ul>\n<p>Implementing SSR within React is possible via <a href=\"https:\/\/reactjs.org\/docs\/react-dom-server.html\">ReactDOMServer<\/a>. However, I recommend using a React framework called <a href=\"https:\/\/nextjs.org\">Next.js<\/a>&nbsp;and <a href=\"https:\/\/nextjs.org\/docs\/basic-features\/pages#static-generation-recommended\">using <\/a><a href=\"https:\/\/nextjs.org\/docs\/basic-features\/pages#static-generation-recommended\">its<\/a><a href=\"https:\/\/nextjs.org\/docs\/basic-features\/pages#static-generation-recommended\">&nbsp;SSG<\/a>&nbsp;and <a href=\"https:\/\/nextjs.org\/docs\/basic-features\/pages#server-side-rendering\">SSR options<\/a>. You can also implement CSR with Next.js, but the framework nudges users toward SSR\/SSG due to&nbsp;speed.<\/p>\n<p>Next.js supports what it&nbsp;calls \u201c<a href=\"https:\/\/nextjs.org\/docs\/advanced-features\/automatic-static-optimization\">Automatic Static Optimization<\/a>.\u201d&nbsp;In&nbsp;practice, this means you can have some pages on a site that use SSR&nbsp;(such as&nbsp;an account page) and other pages using SSG (such as&nbsp;your blog).<\/p>\n<p>The result: SSG and fast TTFB for non-dynamic pages, and SSR as a backup rendering strategy for dynamic content.<\/p>\n<div class=\"sidenote\"><div class=\"sidenote-title\">Sidenote.<\/div> You may have heard about <a href=\"https:\/\/reactjs.org\/docs\/react-dom.html\">React Hydration with <\/a><a href=\"https:\/\/reactjs.org\/docs\/react-dom.html\">ReactDOM.hydrate()<\/a>. 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 <a href=\"https:\/\/reactjs.org\/docs\/handling-events.html\">event handlers<\/a>&nbsp;to HTML that will change. React then keeps HTML between the browser and server in sync. Currently, I can\u2019t recommend this approach&nbsp;because&nbsp;it still has negative implications for web vitals like TTI for the initial render.&nbsp;<a href=\"https:\/\/github.com\/facebook\/react\/pull\/14717\">Partial Hydration<\/a>&nbsp;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&nbsp;then,&nbsp;SSR\/SSG is the better option.<\/div>\n<p>Since we\u2019re talking about speed, I\u2019ll&nbsp;be doing you a disservice by&nbsp;not mentioning other ways Next.js optimizes&nbsp;the <a href=\"https:\/\/developers.google.com\/web\/fundamentals\/performance\/critical-rendering-path\">critical rendering path<\/a>&nbsp;for React applications with features like:<\/p>\n<ul>\n<li><a href=\"https:\/\/nextjs.org\/docs\/basic-features\/image-optimization\">Image optimization<\/a>&nbsp;\u2013&nbsp;This adds width&nbsp;and height&nbsp;&lt;img&gt;&nbsp;attributes and&nbsp;<a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/HTMLImageElement\/srcset\">srcset<\/a>, lazy loading,&nbsp;and image resizing.<\/li>\n<li><a href=\"https:\/\/nextjs.org\/docs\/basic-features\/font-optimization\">Font optimization<\/a>&nbsp;\u2013&nbsp;This inlines critical font CSS and adds&nbsp;controls for <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/CSS\/@font-face\/font-display\">font-display<\/a>.<\/li>\n<li><a href=\"https:\/\/nextjs.org\/docs\/basic-features\/script\">Script optimization<\/a>&nbsp;\u2013&nbsp;This lets you pick&nbsp;when a script should be loaded:&nbsp;before\/after the page is interactive or lazily.<\/li>\n<li><a href=\"https:\/\/nextjs.org\/docs\/advanced-features\/dynamic-import\">Dynamic imports<\/a>&nbsp;\u2013&nbsp;If you implement best practices&nbsp;for <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Glossary\/Code_splitting\">code splitting<\/a>, this feature makes it easier to import JS code when&nbsp;required rather than leaving it to load on the initial render and slowing it&nbsp;down.<\/li>\n<\/ul>\n<p><a href=\"https:\/\/developers.google.com\/search\/blog\/2020\/11\/timing-for-page-experience\">Speed and positive Core Web Vitals are a ranking factor<\/a>, albeit a minor one. Next.js features make it easier to create great web experiences that will give you a competitive advantage.<\/p>\n<div class=\"recommendation\"><div class=\"recommendation-title\">TIP<\/div><div class=\"recommendation-content\">\n<p>Many developers deploy their Next.js web applications using Vercel (the creators of Next.js), which has <a href=\"https:\/\/vercel.com\/docs\/edge-network\/overview\">a global edge network of servers<\/a>; this&nbsp;results in fast load&nbsp;times.<\/p>\n<p>Vercel provides <a href=\"https:\/\/vercel.com\/docs\/concepts\/analytics\/web-vitals\">data on the Core Web Vitals of all sites<\/a>&nbsp;deployed on the platform, but you can also get detailed web vital data for each URL using Ahrefs\u2019 <a href=\"https:\/\/ahrefs.com\/site-audit\">Site Audit<\/a>.<\/p>\n<p>Simply add an API key within the crawl settings of your projects.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-138882\" src=\"https:\/\/ahrefs.com\/blog\/wp-content\/uploads\/2022\/02\/10-add-api-key.png\" alt=\"Text field to add API key\" width=\"1508\" height=\"392\" srcset=\"https:\/\/ahrefs.com\/blog\/wp-content\/uploads\/2022\/02\/10-add-api-key.png 1508w, https:\/\/ahrefs.com\/blog\/wp-content\/uploads\/2022\/02\/10-add-api-key-680x177.png 680w, https:\/\/ahrefs.com\/blog\/wp-content\/uploads\/2022\/02\/10-add-api-key-768x200.png 768w\" sizes=\"auto, (max-width: 1508px) 100vw, 1508px\"><\/p>\n<div style=\"text-align: center;\"><\/div>\n<p>After you\u2019ve run your audit, have a look at the performance area. There, Ahrefs\u2019 <a href=\"https:\/\/ahrefs.com\/site-audit\">Site Audit<\/a>&nbsp;will show you charts displaying data from the Chrome User Experience Report (CrUX) and Lighthouse.<\/p>\n<\/div><\/div>\n<div style=\"text-align: center;\"><img decoding=\"async\" src=\"https:\/\/ahrefs.com\/blog\/wp-content\/uploads\/2022\/02\/11-crux-and-lighthouse-data.png\" alt=\"Pie charts and bar graphs showing data from CrUX and Lighthouse\"><\/div>\n<h3>2. Use status codes correctly<\/h3>\n<p>A common issue with most SPAs is they don\u2019t correctly report <a href=\"https:\/\/ahrefs.com\/blog\/http-status-codes\/\">status codes<\/a>. This is&nbsp;as the server isn\u2019t loading the page\u2014the browser is. You\u2019ll commonly see issues with:<\/p>\n<ul>\n<li>No 3xx redirects, with JavaScript redirects being used instead.<\/li>\n<li>4xx status codes not reporting for \u201cnot found\u201d&nbsp;URLs.<\/li>\n<\/ul>\n<p>You can see below I&nbsp;ran&nbsp;a test on a React site with <a href=\"https:\/\/httpstatus.io\">httpstatus.io<\/a>. This page should obviously be a 404 but,&nbsp;instead, returns a 200 status code. This is called a soft&nbsp;404.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-138884\" src=\"https:\/\/ahrefs.com\/blog\/wp-content\/uploads\/2022\/02\/12-soft-404.jpg\" alt=\"Table showing URL on left. On right, under &quot;Status codes,&quot; it shows &quot;200&quot;\" width=\"1286\" height=\"212\" srcset=\"https:\/\/ahrefs.com\/blog\/wp-content\/uploads\/2022\/02\/12-soft-404.jpg 1286w, https:\/\/ahrefs.com\/blog\/wp-content\/uploads\/2022\/02\/12-soft-404-680x112.jpg 680w, https:\/\/ahrefs.com\/blog\/wp-content\/uploads\/2022\/02\/12-soft-404-768x127.jpg 768w\" sizes=\"auto, (max-width: 1286px) 100vw, 1286px\"><\/p>\n<div style=\"text-align: center;\"><\/div>\n<p>The risk here is that Google may decide to index that page (depending on its&nbsp;content). Google&nbsp;could then serve this to users, or it\u2019ll be used when evaluating a&nbsp;site.<\/p>\n<p>In addition, reporting 404s helps SEOs audit a site. If you accidentally internally link to a 404 page and it\u2019s returning a 200 status code, quickly spotting the area with an auditing tool may become much more challenging.<\/p>\n<p>There are a couple of ways to solve this issue. If you\u2019re client-side rendering:<\/p>\n<ol>\n<li>Use the <a href=\"https:\/\/reactrouter.com\">React Router framework<\/a>.<\/li>\n<li><a href=\"https:\/\/ultimatecourses.com\/blog\/react-router-not-found-component\">Create a 404 component<\/a>&nbsp;that shows when a route isn\u2019t recognized.<\/li>\n<li>Add a noindex tag to \u201cnot found\u201d&nbsp;pages.<\/li>\n<li>Add a &lt;h1&gt; with a message like \u201c404: Page Not Found.\u201d&nbsp;This isn\u2019t ideal, as we don\u2019t report a 404 status code.&nbsp;But it will prevent Google from indexing the page&nbsp;and help it&nbsp;recognize the page as a&nbsp;soft 404.<\/li>\n<li>Use JavaScript redirects when you need to change a URL. Again, not ideal, but Google does follow JavaScript redirects and pass ranking signals.<\/li>\n<\/ol>\n<p><strong>If you\u2019re using SSR<\/strong>, Next.js makes this simple with <a href=\"https:\/\/nextjs.org\/docs\/api-routes\/response-helpers\">response helpers<\/a>,&nbsp;which let you set whatever status code you want, including 3xx redirects or a 4xx status code.&nbsp;The approach I outlined using React Router can also be put into practice&nbsp;while using Next.js. However, if&nbsp;you\u2019re using Next.js, you\u2019re likely also implementing SSR\/SSG.<\/p>\n<h3>3. Avoid hashed URLs<\/h3>\n<p>This issue isn\u2019t as common for React, but it\u2019s essential&nbsp;to avoid hash URLs like the following:<\/p>\n<ul>\n<li>https:\/\/reactspa.com\/#\/shop<\/li>\n<li>https:\/\/reactspa.com\/#\/about<\/li>\n<li>https:\/\/reactspa.com\/#\/contact<\/li>\n<\/ul>\n<p>Generally, Google isn\u2019t going to see anything after the hash. All of these pages will be seen as https:\/\/reactspa.com\/.<\/p>\n<h4>Solution<\/h4>\n<p>SPAs with client-side routing should implement the History API to change pages.<\/p>\n<p>You can do this relatively easily <a href=\"https:\/\/danthareja.gitbooks.io\/react-router-tutorial\/content\/lessons\/10-clean-urls\/\">with both React Router<\/a>&nbsp;and <a href=\"https:\/\/nextjs.org\/docs\/api-reference\/next\/router\">Next.js<\/a>.<\/p>\n<h3>4. Use &lt;a href&gt; links where relevant<\/h3>\n<p>A common mistake with SPAs is&nbsp;using a &lt;div&gt; or a &lt;button&gt; to change&nbsp;the URL. This isn\u2019t an issue with React itself, but how the library is&nbsp;used.<\/p>\n<p>Doing this&nbsp;presents an issue with search engines. As mentioned earlier, when Google processes a URL,&nbsp;it&nbsp;looks for additional URLs to crawl within &lt;a href&gt;&nbsp;elements.<\/p>\n<p>If the &lt;a href&gt;&nbsp;element is missing, Google won\u2019t crawl the URLs and <a href=\"https:\/\/ahrefs.com\/blog\/google-pagerank\/\">pass PageRank<\/a>.<\/p>\n<h4>Solution<\/h4>\n<p>The solution is to include&nbsp;&lt;a href&gt;&nbsp;links&nbsp;to&nbsp;URLs that you want Google to discover.<\/p>\n<p>Checking whether you\u2019re linking to a URL correctly is easy. Inspect the element that internally links and check the HTML to ensure you\u2019ve included&nbsp;&lt;a href&gt;&nbsp;links.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-138885\" src=\"https:\/\/ahrefs.com\/blog\/wp-content\/uploads\/2022\/02\/13-check-for-ahref-links.png\" alt=\"HTML with no <a href> links\" width=\"1242\" height=\"276\" srcset=\"https:\/\/ahrefs.com\/blog\/wp-content\/uploads\/2022\/02\/13-check-for-ahref-links.png 1242w, https:\/\/ahrefs.com\/blog\/wp-content\/uploads\/2022\/02\/13-check-for-ahref-links-680x151.png 680w, https:\/\/ahrefs.com\/blog\/wp-content\/uploads\/2022\/02\/13-check-for-ahref-links-768x171.png 768w\" sizes=\"auto, (max-width: 1242px) 100vw, 1242px\"><\/p>\n<p>As in the above example, you may have an issue if they aren\u2019t.<\/p>\n<p>However, it\u2019s essential&nbsp;to understand that missing&nbsp;&lt;a href&gt;&nbsp;links aren\u2019t always an issue. One benefit of CSR is that when content is helpful to&nbsp;users but not search engines, you can change the content client-side and not include the &lt;a href&gt;&nbsp;link.<\/p>\n<p>In the above example, the site uses&nbsp;<a href=\"https:\/\/ahrefs.com\/blog\/faceted-navigation\/\">faceted navigation<\/a>&nbsp;that links to potentially millions of combinations of filters that aren\u2019t useful for a search engine to crawl or&nbsp;index.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-138895\" src=\"https:\/\/ahrefs.com\/blog\/wp-content\/uploads\/2022\/02\/14-genres.png\" alt=\"List of genres \" width=\"580\" height=\"502\" srcset=\"https:\/\/ahrefs.com\/blog\/wp-content\/uploads\/2022\/02\/14-genres.png 580w, https:\/\/ahrefs.com\/blog\/wp-content\/uploads\/2022\/02\/14-genres-491x425.png 491w\" sizes=\"auto, (max-width: 580px) 100vw, 580px\"><\/p>\n<div style=\"text-align: center;\"><\/div>\n<p>Loading these filters client-side makes sense here, as the site will conserve <a href=\"https:\/\/ahrefs.com\/blog\/crawl-budget\/\">crawl budget<\/a>&nbsp;by not adding &lt;a href&gt;&nbsp;links for Google to&nbsp;crawl.<\/p>\n<p>Next.js makes this easy with <a href=\"https:\/\/nextjs.org\/learn\/basics\/navigate-between-pages\/link-component\">its link component<\/a>,&nbsp;which you can configure <a href=\"https:\/\/nextjs.org\/learn\/basics\/navigate-between-pages\/client-side\">to allow client-side navigation<\/a>.<\/p>\n<p>If you\u2019ve decided to implement a fully CSR application, <a href=\"https:\/\/v5.reactrouter.com\/web\/api\/Hooks\/usehistory\">you can change URLs with React Router<\/a>&nbsp;using <a href=\"https:\/\/www.w3schools.com\/jsref\/event_onclick.asp\">onClick<\/a>&nbsp;and the <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/History_API\">History API<\/a>.<\/p>\n<h3>5. Avoid lazy loading essential HTML<\/h3>\n<p>It\u2019s common&nbsp;for sites developed with React to inject content into the DOM when a user clicks or hovers over an element\u2014simply because the library makes that easy to&nbsp;do.<\/p>\n<p>This isn\u2019t inherently bad, but content added to the DOM this way will not <a href=\"https:\/\/www.seroundtable.com\/google-links-onclick-javascript-25585.html\">be seen by search engines<\/a>. If the content injected includes important textual content or internal links, this may&nbsp;negatively impact:<\/p>\n<ul>\n<li>How well the page performs (as Google won\u2019t see the content).<\/li>\n<li>The discoverability of other URLs (as Google won\u2019t find the internal links).<\/li>\n<\/ul>\n<p>Here\u2019s an example on a React JS site I recently audited. Here, I\u2019ll show&nbsp;a well-known&nbsp;e-commerce brand with&nbsp;important internal links within its&nbsp;faceted navigation.<\/p>\n<p>However, a modal showing the navigation on mobile was injected into the DOM when you clicked a \u201cFilter\u201d button. Watch the second &lt;!----&gt;&nbsp;within the HTML below to see this in practice:<\/p>\n<div style=\"text-align: center;\"><img decoding=\"async\" src=\"https:\/\/ahrefs.com\/blog\/wp-content\/uploads\/2022\/02\/15-navigation-injected-into-dom.gif\" alt=\"Gif of modal showing the navigation on mobile was injected into DOM\"><\/div>\n<h4>Solution<\/h4>\n<p>Spotting these issues isn\u2019t easy.&nbsp;And as far as I know, no tool will directly tell you about&nbsp;them.<\/p>\n<p>Instead, you should check for common elements such&nbsp;as:<\/p>\n<ul>\n<li>Accordions<\/li>\n<li>Modals<\/li>\n<li>Tabs<\/li>\n<li>Mega menus<\/li>\n<li>Hamburger menus<\/li>\n<\/ul>\n<p>You\u2019ll then need to inspect the element&nbsp;on them and watch what happens with the HTML as you open\/close them by clicking or hovering (as&nbsp;I have done in the above&nbsp;GIF).<\/p>\n<p>Suppose&nbsp;you notice JavaScript is adding HTML to the page. In that case,&nbsp;you\u2019ll need to work with the developers. This is so&nbsp;that rather than injecting the content into the DOM,&nbsp;it\u2019s included within the HTML by default and is hidden and shown via CSS using properties like <a href=\"https:\/\/www.thoughtco.com\/display-none-vs-visibility-hidden-3466884\">visibility: hidden;&nbsp;or display: none;<\/a>.<\/p>\n<h3>6. Don\u2019t forget the fundamentals<\/h3>\n<p>While there are additional SEO considerations with React applications, that doesn\u2019t mean other fundamentals don\u2019t&nbsp;apply.<\/p>\n<p>You\u2019ll still need to make sure your React applications follow best practices for:<\/p>\n<ul>\n<li><a href=\"https:\/\/ahrefs.com\/blog\/canonicalization\/\">Canonicalization<\/a><\/li>\n<li><a href=\"https:\/\/ahrefs.com\/blog\/schema-markup\/\" data-ahr=\"https:\/\/ahrefs.com\/blog\/structured-data\/\">Structured data<\/a><\/li>\n<li><a href=\"https:\/\/ahrefs.com\/blog\/how-to-create-a-sitemap\/\">XML sitemaps<\/a><\/li>\n<li><a href=\"https:\/\/ahrefs.com\/blog\/mobile-first-indexing\/\">Mobile-first<\/a><\/li>\n<li><a href=\"https:\/\/ahrefs.com\/blog\/website-structure\/\">Website structure<\/a><\/li>\n<li><a href=\"https:\/\/ahrefs.com\/blog\/what-is-https\/\">HTTPS<\/a><\/li>\n<li><a href=\"https:\/\/ahrefs.com\/blog\/title-tag-seo\/\">Title tags<\/a><\/li>\n<li><a href=\"https:\/\/ahrefs.com\/blog\/semantic-search\/\">Semantic HTML<\/a><\/li>\n<\/ul>\n<h2>Final thoughts<\/h2>\n<p>Unfortunately, working with React applications does add to the already long list of issues a technical SEO needs to check. But thanks to frameworks like Next.js, it makes the work of an SEO much more straightforward&nbsp;than what it was historically.<\/p>\n<p>Hopefully,&nbsp;this guide has helped you better understand the additional considerations you need to make as an SEO when working with React applications.<\/p>\n<p>Have any questions on working with React? <a href=\"https:\/\/twitter.com\/SamUnderwoodUK\">Tweet me<\/a><a href=\"https:\/\/twitter.com\/SamUnderwoodUK\">.<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>React and other similar libraries (like Vue.js) are becoming the de&nbsp;facto choice for larger businesses that require complex development where a more simplistic approach&nbsp;(like using a WordPress theme)&nbsp;won\u2019t satisfy the requirements. Despite that, SEOs did not initially embrace libraries like<span class=\"ellipsis\">\u2026<\/span><\/p>\n<div class=\"read-more\">Read more \u203a<\/div>\n<p><!-- end of .read-more --><\/p>\n","protected":false},"author":162,"featured_media":138899,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"wp_typography_post_enhancements_disabled":false,"footnotes":""},"categories":[329],"tags":[],"coauthors":[423],"class_list":["post-138897","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-technical-seo","odd"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.3 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>React SEO: Best Practices to Make It SEO-Friendly<\/title>\n<meta name=\"description\" content=\"As React gains popularity, SEOs should learn what it is, how to render with it, and the solutions to some common SEO issues.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/ahrefs.com\/blog\/react-seo\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"React SEO: Best Practices to Make It SEO-Friendly\" \/>\n<meta property=\"og:description\" content=\"Best practices you need to know.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/ahrefs.com\/blog\/react-seo\/\" \/>\n<meta property=\"og:site_name\" content=\"SEO Blog by Ahrefs\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/Ahrefs\/\" \/>\n<meta property=\"article:published_time\" content=\"2022-03-01T07:00:14+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-06-16T22:16:04+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/ahrefs.com\/blog\/wp-content\/uploads\/2022\/02\/fb_react_seo.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"630\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Sam Underwood\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:description\" content=\"Best practices you need to know.\" \/>\n<meta name=\"twitter:creator\" content=\"@SamUnderwoodUK\" \/>\n<meta name=\"twitter:site\" content=\"@ahrefs\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/ahrefs.com\\\/blog\\\/react-seo\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/ahrefs.com\\\/blog\\\/react-seo\\\/\"},\"author\":{\"name\":\"Sam Underwood\",\"@id\":\"https:\\\/\\\/ahrefs.com\\\/blog\\\/#\\\/schema\\\/person\\\/7a4e7e6b862119be5f43a0c5783888d5\"},\"headline\":\"React SEO: Best Practices to Make It SEO-Friendly\",\"datePublished\":\"2022-03-01T07:00:14+00:00\",\"dateModified\":\"2024-06-16T22:16:04+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/ahrefs.com\\\/blog\\\/react-seo\\\/\"},\"wordCount\":3510,\"publisher\":{\"@id\":\"https:\\\/\\\/ahrefs.com\\\/blog\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/ahrefs.com\\\/blog\\\/react-seo\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/ahrefs.com\\\/blog\\\/wp-content\\\/uploads\\\/2022\\\/02\\\/fb_react_seo.png\",\"articleSection\":[\"Technical SEO\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/ahrefs.com\\\/blog\\\/react-seo\\\/\",\"url\":\"https:\\\/\\\/ahrefs.com\\\/blog\\\/react-seo\\\/\",\"name\":\"React SEO: Best Practices to Make It SEO-Friendly\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/ahrefs.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/ahrefs.com\\\/blog\\\/react-seo\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/ahrefs.com\\\/blog\\\/react-seo\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/ahrefs.com\\\/blog\\\/wp-content\\\/uploads\\\/2022\\\/02\\\/fb_react_seo.png\",\"datePublished\":\"2022-03-01T07:00:14+00:00\",\"dateModified\":\"2024-06-16T22:16:04+00:00\",\"description\":\"As React gains popularity, SEOs should learn what it is, how to render with it, and the solutions to some common SEO issues.\",\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/ahrefs.com\\\/blog\\\/react-seo\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/ahrefs.com\\\/blog\\\/react-seo\\\/#primaryimage\",\"url\":\"https:\\\/\\\/ahrefs.com\\\/blog\\\/wp-content\\\/uploads\\\/2022\\\/02\\\/fb_react_seo.png\",\"contentUrl\":\"https:\\\/\\\/ahrefs.com\\\/blog\\\/wp-content\\\/uploads\\\/2022\\\/02\\\/fb_react_seo.png\",\"width\":1200,\"height\":630},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/ahrefs.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/ahrefs.com\\\/blog\\\/\",\"name\":\"SEO Blog by Ahrefs\",\"description\":\"Link Building Strategies &amp; SEO Tips\",\"publisher\":{\"@id\":\"https:\\\/\\\/ahrefs.com\\\/blog\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/ahrefs.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/ahrefs.com\\\/blog\\\/#organization\",\"name\":\"Ahrefs\",\"url\":\"https:\\\/\\\/ahrefs.com\\\/blog\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/ahrefs.com\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/ahrefs.com\\\/blog\\\/wp-content\\\/uploads\\\/2023\\\/06\\\/ahrefs-logo.png\",\"contentUrl\":\"https:\\\/\\\/ahrefs.com\\\/blog\\\/wp-content\\\/uploads\\\/2023\\\/06\\\/ahrefs-logo.png\",\"width\":2048,\"height\":768,\"caption\":\"Ahrefs\"},\"image\":{\"@id\":\"https:\\\/\\\/ahrefs.com\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/Ahrefs\\\/\",\"https:\\\/\\\/x.com\\\/ahrefs\",\"https:\\\/\\\/www.linkedin.com\\\/company\\\/ahrefs\\\/\",\"https:\\\/\\\/www.youtube.com\\\/c\\\/ahrefscom\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/ahrefs.com\\\/blog\\\/#\\\/schema\\\/person\\\/7a4e7e6b862119be5f43a0c5783888d5\",\"name\":\"Sam Underwood\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/ahrefs.com\\\/blog\\\/wp-content\\\/uploads\\\/2021\\\/09\\\/sam-underwood.jpg0aa3181310d847d8be2845189fc2b794\",\"url\":\"https:\\\/\\\/ahrefs.com\\\/blog\\\/wp-content\\\/uploads\\\/2021\\\/09\\\/sam-underwood.jpg\",\"contentUrl\":\"https:\\\/\\\/ahrefs.com\\\/blog\\\/wp-content\\\/uploads\\\/2021\\\/09\\\/sam-underwood.jpg\",\"caption\":\"Sam Underwood\"},\"description\":\"Sam Underwood is a solo consultant helping ecommerce businesses grow their organic revenue via on-page SEO, technical SEO, and content strategies.\",\"sameAs\":[\"https:\\\/\\\/www.samunderwood.co.uk\\\/\",\"https:\\\/\\\/www.linkedin.com\\\/in\\\/samunderwooduk\\\/\",\"https:\\\/\\\/x.com\\\/SamUnderwoodUK\"],\"url\":\"https:\\\/\\\/ahrefs.com\\\/blog\\\/author\\\/sam-underwood\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"React SEO: Best Practices to Make It SEO-Friendly","description":"As React gains popularity, SEOs should learn what it is, how to render with it, and the solutions to some common SEO issues.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/ahrefs.com\/blog\/react-seo\/","og_locale":"en_US","og_type":"article","og_title":"React SEO: Best Practices to Make It SEO-Friendly","og_description":"Best practices you need to know.","og_url":"https:\/\/ahrefs.com\/blog\/react-seo\/","og_site_name":"SEO Blog by Ahrefs","article_publisher":"https:\/\/www.facebook.com\/Ahrefs\/","article_published_time":"2022-03-01T07:00:14+00:00","article_modified_time":"2024-06-16T22:16:04+00:00","og_image":[{"width":1200,"height":630,"url":"https:\/\/ahrefs.com\/blog\/wp-content\/uploads\/2022\/02\/fb_react_seo.png","type":"image\/png"}],"author":"Sam Underwood","twitter_card":"summary_large_image","twitter_description":"Best practices you need to know.","twitter_creator":"@SamUnderwoodUK","twitter_site":"@ahrefs","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/ahrefs.com\/blog\/react-seo\/#article","isPartOf":{"@id":"https:\/\/ahrefs.com\/blog\/react-seo\/"},"author":{"name":"Sam Underwood","@id":"https:\/\/ahrefs.com\/blog\/#\/schema\/person\/7a4e7e6b862119be5f43a0c5783888d5"},"headline":"React SEO: Best Practices to Make It SEO-Friendly","datePublished":"2022-03-01T07:00:14+00:00","dateModified":"2024-06-16T22:16:04+00:00","mainEntityOfPage":{"@id":"https:\/\/ahrefs.com\/blog\/react-seo\/"},"wordCount":3510,"publisher":{"@id":"https:\/\/ahrefs.com\/blog\/#organization"},"image":{"@id":"https:\/\/ahrefs.com\/blog\/react-seo\/#primaryimage"},"thumbnailUrl":"https:\/\/ahrefs.com\/blog\/wp-content\/uploads\/2022\/02\/fb_react_seo.png","articleSection":["Technical SEO"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/ahrefs.com\/blog\/react-seo\/","url":"https:\/\/ahrefs.com\/blog\/react-seo\/","name":"React SEO: Best Practices to Make It SEO-Friendly","isPartOf":{"@id":"https:\/\/ahrefs.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/ahrefs.com\/blog\/react-seo\/#primaryimage"},"image":{"@id":"https:\/\/ahrefs.com\/blog\/react-seo\/#primaryimage"},"thumbnailUrl":"https:\/\/ahrefs.com\/blog\/wp-content\/uploads\/2022\/02\/fb_react_seo.png","datePublished":"2022-03-01T07:00:14+00:00","dateModified":"2024-06-16T22:16:04+00:00","description":"As React gains popularity, SEOs should learn what it is, how to render with it, and the solutions to some common SEO issues.","inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/ahrefs.com\/blog\/react-seo\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/ahrefs.com\/blog\/react-seo\/#primaryimage","url":"https:\/\/ahrefs.com\/blog\/wp-content\/uploads\/2022\/02\/fb_react_seo.png","contentUrl":"https:\/\/ahrefs.com\/blog\/wp-content\/uploads\/2022\/02\/fb_react_seo.png","width":1200,"height":630},{"@type":"WebSite","@id":"https:\/\/ahrefs.com\/blog\/#website","url":"https:\/\/ahrefs.com\/blog\/","name":"SEO Blog by Ahrefs","description":"Link Building Strategies &amp; SEO Tips","publisher":{"@id":"https:\/\/ahrefs.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/ahrefs.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/ahrefs.com\/blog\/#organization","name":"Ahrefs","url":"https:\/\/ahrefs.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/ahrefs.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/ahrefs.com\/blog\/wp-content\/uploads\/2023\/06\/ahrefs-logo.png","contentUrl":"https:\/\/ahrefs.com\/blog\/wp-content\/uploads\/2023\/06\/ahrefs-logo.png","width":2048,"height":768,"caption":"Ahrefs"},"image":{"@id":"https:\/\/ahrefs.com\/blog\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/Ahrefs\/","https:\/\/x.com\/ahrefs","https:\/\/www.linkedin.com\/company\/ahrefs\/","https:\/\/www.youtube.com\/c\/ahrefscom"]},{"@type":"Person","@id":"https:\/\/ahrefs.com\/blog\/#\/schema\/person\/7a4e7e6b862119be5f43a0c5783888d5","name":"Sam Underwood","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/ahrefs.com\/blog\/wp-content\/uploads\/2021\/09\/sam-underwood.jpg0aa3181310d847d8be2845189fc2b794","url":"https:\/\/ahrefs.com\/blog\/wp-content\/uploads\/2021\/09\/sam-underwood.jpg","contentUrl":"https:\/\/ahrefs.com\/blog\/wp-content\/uploads\/2021\/09\/sam-underwood.jpg","caption":"Sam Underwood"},"description":"Sam Underwood is a solo consultant helping ecommerce businesses grow their organic revenue via on-page SEO, technical SEO, and content strategies.","sameAs":["https:\/\/www.samunderwood.co.uk\/","https:\/\/www.linkedin.com\/in\/samunderwooduk\/","https:\/\/x.com\/SamUnderwoodUK"],"url":"https:\/\/ahrefs.com\/blog\/author\/sam-underwood\/"}]}},"_links":{"self":[{"href":"https:\/\/ahrefs.com\/blog\/wp-json\/wp\/v2\/posts\/138897","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ahrefs.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ahrefs.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ahrefs.com\/blog\/wp-json\/wp\/v2\/users\/162"}],"replies":[{"embeddable":true,"href":"https:\/\/ahrefs.com\/blog\/wp-json\/wp\/v2\/comments?post=138897"}],"version-history":[{"count":0,"href":"https:\/\/ahrefs.com\/blog\/wp-json\/wp\/v2\/posts\/138897\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/ahrefs.com\/blog\/wp-json\/wp\/v2\/media\/138899"}],"wp:attachment":[{"href":"https:\/\/ahrefs.com\/blog\/wp-json\/wp\/v2\/media?parent=138897"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ahrefs.com\/blog\/wp-json\/wp\/v2\/categories?post=138897"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ahrefs.com\/blog\/wp-json\/wp\/v2\/tags?post=138897"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/ahrefs.com\/blog\/wp-json\/wp\/v2\/coauthors?post=138897"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}