How to add SEO to your NextJS Web-App
Introduction:
Have you ever developed something cool, and revolutionary, and cannot wait to share it with the whole world?
You start ticking items off your checklist:
- [x] Optimize the build,
- [x] Purchase a domain,
- [x] Push it to production and
- [x] Send it to your friend.
BUT…
As soon as you share it on any social media platform, it shows the ‘web link’ as the website carousel. Or worse of all, it reads ‘React App’!
(Your conversation with your friend)
Yeah, I am the kind of loner to talk to myself.
Moving on, let us understand what mistakes you made due to which you failed to impress your friends (or Boss, or Hiring Manager, or someone I don’t care to list).
Whoever you failed to impress, the answer is a three-letter abbreviation: SEO, that you failed to research and incorporate in your web app.
What is SEO and why is it needed?
- S - Search
- E - Engine
- O - Optimization, is a website optimizing technique for search engines more important than ever. And, let us face it head-on, SEO is a critical part of any business's online presence.
When someone has a question and wants to look up the answer online, they use search engines. Search engine algorithms are computer programs that sift through data to provide users with the precise results they want.
To identify websites and choose which ones to rank for a particular keyword, search engines use algorithms. In order to find information, search engines go through three stages, and they are:
- Crawling - the discovery stage
- Indexing - the filing stage
- Ranking - the retrieval stage.
If you are interested to read more on this topic, I would suggest that you read this article on SEO.
The key takeaway for any developer from the above article is that every Search Engine (such as Google, DuckDuckGo, Bing, etc.) employ bots called ‘crawlers’ that analyze and rank your web pages according to the content inside them.
Though these crawlers sift through your website, they are not very smart at understanding what the content really is, and hence, we have something called metadata
to feed these bots the information that they need to rank your website on a search engine. In 21st Century, this ranking is done by using a protocol called 'The Open Graph protocol'. Feel free to read more about the 'OGP' at https://ogp.me/.
Let us not get ahead of ourselves, and understand what all components truly contribute to your SEO score.
SEO and Rendering in React apps:
One of the crucial thing for SEO is that page data and metadata is available on page load without JavaScript.
Let us understand why React is not the wisest choice for creating an SEO-optimized website.
After countless hours of development and debugging, when you are done programming and testing your web app on dev servers, it’s time to move your app to production, having multiple JavaScript or CSS files isn’t ideal. When a user visits your site, each of your files will require an additional HTTP request, making your site slower to load. So to remedy this, you can create a “build” of our app, which merges all your CSS files into one file, and does the same with your JavaScript. This way, you minimize the number and size of files the user gets. To create this “build”, you use a “build tool”. This can be done by running the npm ‘build’ command:
npm run build
The only downside to this React Build is that it is just a bunch of gibberish to humans and crawlers, and is only compiled on page load.
Sample React build:
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="./logo512.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="/logo192.png"/><link rel="manifest" href="/manifest.json"/><link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin><link href="https://fonts.googleapis.com/css2?family=Open+Sans:wght@300;400;600;700;800&display=swap" rel="stylesheet"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.5.0/font/bootstrap-icons.css"><title>[Dev] - Dashboard</title><link href="/static/css/main.ceb09c0b.chunk.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script>!function(e){function r(r){for(var n,u,i=r[0],c=r[1],l=r[2],s=0,p=[];s<i.length;s++)u=i[s],Object.prototype.hasOwnProperty.call(o,u)&&o[u]&&p.push(o[u][0]),o[u]=0;for(n in c)Object.prototype.hasOwnProperty.call(c,n)&&(e[n]=c[n]);for(f&&f(r);p.length;)p.shift()();return a.push.apply(a,l||[]),t()}function t(){for(var e,r=0;r<a.length;r++){for(var t=a[r],n=!0,i=1;i<t.length;i++){var c=t[i];0!==o[c]&&(n=!1)}n&&(a.splice(r--,1),e=u(u.s=t[0]))}return e}var n={},o={1:0},a=[];function u(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,u),t.l=!0,t.exports}u.e=function(e){var r=[],t=o[e];if(0!==t)if(t)r.push(t[2]);else{var n=new Promise((function(r,n){t=o[e]=[r,n]}));r.push(t[2]=n);var a,i=document.createElement("script");i.charset="utf-8",i.timeout=120,u.nc&&i.setAttribute("nonce",u.nc),i.src=function(e){return u.p+"static/js/"+({}[e]||e)+"."+{3:"528a8571"}[e]+".chunk.js"}(e);var c=new Error;a=function(r){i.onerror=i.onload=null,clearTimeout(l);var t=o[e];if(0!==t){if(t){var n=r&&("load"===r.type?"missing":r.type),a=r&&r.target&&r.target.src;c.message="Loading chunk "+e+" failed.\n("+n+": "+a+")",c.name="ChunkLoadError",c.type=n,c.request=a,t[1](c)}o[e]=void 0}};var l=setTimeout((function(){a({type:"timeout",target:i})}),12e4);i.onerror=i.onload=a,document.head.appendChild(i)}return Promise.all(r)},u.m=e,u.c=n,u.d=function(e,r,t){u.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},u.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},u.t=function(e,r){if(1&r&&(e=u(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(u.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)u.d(t,n,function(r){return e[r]}.bind(null,n));return t},u.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return u.d(r,"a",r),r},u.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},u.p="/",u.oe=function(e){throw console.error(e),e};var i=this["webpackJsonptransfer-dashboard"]=this["webpackJsonptransfer-dashboard"]||[],c=i.push.bind(i);i.push=r,i=i.slice();for(var l=0;l<i.length;l++)r(i[l]);var f=c;t()}([])</script><script src="/static/js/2.570eb894.chunk.js"></script><script src="/static/js/main.0608212f.chunk.js"></script></body></html>
Crawlers and humans can only make out gibberish from this build. Hence, we need a method to load the page without JavaScript.
Different Rendering Methods and how they affect your SEO Score:
For this section I would like to take direct reference from NextJS Documentation. Feel free to skip this technical section if you just want working solutions.
Otherwise…
Rendering Strategies
Static Site Generation (SSG)
Static Site Generation is where your HTML is generated at build time. Each request then makes use of this HTML. Since all the HTML is pre-rendered and available on page load, static site generation is probably the greatest type of rendering method for SEO. It also improves page performance, which is now another ranking criterion for SEO.
Server-Side Rendering (SSR)
Server-Side Rendering (SSR), like SSG, is pre-rendered, making it excellent for SEO. HTML in SSR is created at request time as opposed to build time like in SSG. When you haveextremely dynamic pages, this is fantastic.
Incremental Static Regeneration (ISR)
It might not be possible to generate every page at build time if you have a lot of them. Next. After you've constructed your website, JavaScript enables you to create or change static pages.
Developers and content editors can employ static generation on a per-page basis with incremental static regeneration instead of having to completely rebuild the site. You may scale to millions of pages while maintaining the advantages of static using ISR.
Client Side Rendering (CSR)
Developers can use JavaScript and client-side rendering to completely render their websites in the browser. Up until you retrieve the JavaScript and the browser compiles everything, a single HTML file with little to no content is often delivered as the initial page load.
As we mentioned previously, client-side rendering is generally not advised for the best SEO.
CSR is ideal for dashboards with lots of data, account pages, or any other page that you don't need to be indexed by any search engines.
Next - SEO
One of the major strengths of Next.js is that each one of the above rendering methods can be done on a per-page basis. You might want your blog posts (like this one) statically generated, your customers, account dashboard client-side rendered and, then perhaps you have a news feed you want to server-side rendering.
Finally,
we are on the interesting and functioning part of the blog. The implementation!
We would be looking at the NextJS web app for this section. In your _app.js
or _app.ts
, you can add the following metadata:
-
Title
Title
meta tag is important on your web page for 2 big reasons:- It is what users see when they click to enter your website from search results
- It provides the crawler with your website name so that it can understand and index it on Search Engines.
<meta name="og:title" content="SEO Optimzation using NextJS" />
-
Description
Description
is another meta tag that is important for your website. The keywords from the description will appear in bold if a user's search contains them.
<meta name="description" content="Blog on implmenting SEO optimization using NextJS." />
-
Viewport
Viewport
meta tag tells a Search Engine that the website is mobile screen friendly. If your website is responsive, this is an important meta tag to include.
<meta name="viewport" content="width=device-width, initial-scale=1" />
-
Author
Author
meta tag tells the crawler about the owner/author of the website. This way when the author is googled, his websites are also listed on the search engine.
<meta name="author" content="Kanit Mann" />
-
Robots
Robots
meta tag tells what all robots and crawlers are allowed to sift through your website.
<meta name="robots" content="all" />
Example:
This is the <Head>
snippet from my Portfolio Website, which not only helps me optimize it for SEO but also brings out a pop up when shared through social media.
<Head>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="description" content="Kanit Mann is a tech enthusiast with entry-level industrial experience in Database Management, Web Development, and Embedded Programming." />
<meta name="author" content="Kanit Mann" />
<meta name="author" content="kanitmann" />
<meta name="robots" content="all" />
<meta name="robots" content="max-image-preview:standard" />
<link rel="apple-touch-icon" href="apple-touch-icon.png" />
<link rel="shortcut icon" href="/apple-touch-icon.png" type="image/apple-touch-icon.png" />
<meta name="twitter:title" content="Kanit Mann" />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:site" content="@mannkanit" />
<meta name="twitter:creator" content="@mannkanit" />
<meta name="twitter:image" content="https://raw.githubusercontent.com/kanitmann/portfoliov2/master/public/card.png" />
<meta property="og:site_name" content="Kanit Mann" />
<meta name="og:title" content="Kanit Mann" />
<meta property="og:type" content="website" />
<meta property="og:image:url" content="https://raw.githubusercontent.com/kanitmann/portfoliov2/master/public/card.png" />
<meta property="og:image:type" content="image/png" />
<meta property="og:image:width" content="400" />
<meta property="og:image:height" content="300" />
<meta property="og:image:alt" content="A screenshot image of Kanit's homepage" />
<title>Kanit Mann - Homepage</title>
</Head>
And Voila!
All your friends start trusting you blindly.
If you find this blog helpful, kindly add me as friend, I am very lonely 😭
Top comments (0)