Unlock the Benefits of Next.JS: Get the Most Out of It!

Author
Category
Time to read
0 minutes
Date

Introduction

Next.js is a React framework that allows you to build SEO-friendly, and extremely user-facing static websites and web applications. It allows you to use different rendering methods and has TypeScript support, smart bundling, route prefetching, and much more.

What is Next.js, and how does it help with SEO?

Next.js is a React framework that allows you to build search engine-friendly, and extremely user-facing static websites and web applications. It allows you to use different rendering methods and has TypeScript support, smart bundling, route prefetching, and much more. Next.JS is great for search engine optimization because makes it easy to make your website fast and search engine-compliant. Next.JS is not a single-page application but rather a multiple-page file-based react app.

Next.JS is a lifesaver for very big websites (1000+ pages), programmatic pages and web pages that heavily depend on data that needs frequent updating. These websites benefit from the usage of different rendering methods depending on if the page is visited frequently and if the data needs to be updated periodically. Next.JS also make it easy to statically generate websites which is great for SEO optimization. Static site generation makes website pages faster than client-side or server-side generation.

What are Next.JS’s Advantages and why should you use Next.JS?

Next.js is a React framework that allows you to build SEO-friendly, and extremely user-facing static websites and web applications. It allows you to use different rendering methods and has TypeScript support, smart bundling, route prefetching, and much more. Next.JS lets you develop SEO-compliant websites.

Next.JS is great for SEO because makes it easy to make your website fast and SEO-compliant. NextJs offers a number of features that help to do so. Next.JS is a lifesaver for very big websites (1000+ pages), programmatic pages and websites that heavily depend on data that needs frequent updating. These websites benefit from the usage of different rendering methods depending on if the page is visited frequently and if the data needs to be updated periodically. If you run a blog with 10 pages, you can simply build the whole site with ISR and you should be fine.

What are Next.JS Disadvantages?

It is often mentioned that Next.JS is opinionated and that this is a bad thing. From my perspective, when it comes to SEO there are a lot of mistakes beginners (and even advanced) users can make. An opinionated framework like Next.JS helps to reduce those mistakes. If you have a huge website with 10,000+ pages, you will be thankful that Next.JS is opinionated.

Routing is often a topic of debate since it is not as flexible as some developers wish it would be. Routing is page-based, where you specify whether to generate those pages server-side, client-side or static (or ISR). You can rewrite and redirects though to send the requests to a different location.

Building SEO is not easy and it is hard to find the right talent for it. Specifically, most developers do not have experience with SEO (let alone being interested in it) and they will likely make a lot of mistakes. The technical SEO auditor has most likely never coded and might not be able to give very actionable advice on how to fix possible issues. Most likely, the website will not be SEO-optimised and it can take up to 12 months (for big websites) to detect and fix indexing, speed and core web vital errors.

Creating a new react app with Next.JS, TypeScript and Tailwind

To start a new next.js project (without typescript), you can follow these commands. This will automatically set up the project and folder structure for you.

npx create-next-app@latest
# or
yarn create next-app
# or
pnpm create next-app

It is straightforward to start a new next.js project with typescript (see below). In the tsconfig.json, you can customise the compiler, read more about all options here.

npx create-next-app@latest --ts
# or
yarn create next-app --typescript
# or
pnpm create next-app --ts

You can specify path mappings. For example, if you want to avoid ugly imports, you can map the most important paths.

# ts.config
    
"paths": {
      "@/*": ["./src/*"],
	  "@/api/*": ["./src/api/*"],
	  "@/utils/*": ["./src/utils/*"],
	  "@/rendering/*": ["./src/rendering/*"],
	  "@/components/*": ["./src/components/*"],
	  "@/common/*": ["./src/common/*"],

    }
#  Ugly imports
import {GetData} from '../../../api'
# Now
import {GetData} from '@/api/'

Next.JS makes it easy to manage SEO metadata and meta tags

The title (arguably the most important metadata) and description (reportedly no emphasis is placed on it anymore), and other meta tags can be simply added to the head like this:

import Head from 'next/head';

function Index() {
  return (
    <div>
      <Head>
        <title>
          My first website
        </title>
        <meta
          name="description"
          content="Check out my new website"
        />
      </Head>
      <h1>My first website</h1>
    </div>
  );
}

export default Index;

The open graph protocol standardized how metadata is structured so that in the event of the page being shared on social media, all metadata is correct. In other words, the open graph protocol is not important for search engine optimization, but it is important for the correct display on social media platforms. You simply prepend the open graph tag: “og:” to the meta tags in the head component and add all your open graph tags accordingly.

<meta
          property="og:description"
          content="This text here should show up when someone shares the link on social media"
  />
<meta
          property="og:image"
          content="https://myfirstwebsite.com/this_is_me.jpg"
/>

You can also add further structured data to the head. For an overview of possible schemas, you can refer to schema.org. Adding schemas to your page is very helpful for indexing by search engines. For example, having a schema for jobs will make your jobs pop up in the google for jobs marketplace (and drive substantial traffic).

It is highly recommended to hard-code or pre-render your meta-data. If your metadata depends on the execution of Javascript, it is likely that search engine bots will not be able to read it on their first pass of your website crawling phase.

Why is Next JS good for SEO?

Next.JS has a number of specific features and tools which make it great for SEO.

Rendering methods of Next.Js

Next.JS offers a number of rendering methods. Here, the rendering methods are ordered from fastest to slowest.

Pre-rendered HTML pages

Static Pages:

The HTML is generated during build time. This fastest and most preferred method to render a page if you do not expect the page to update at all (or very infrequently). Some pages might almost never really update (e.g. About-Us, Privacy Policy) and you can just deploy your site again so that it reflects the change. In case your pages might update after the deployment, you can use Incremental Static Rendering (ISR). For a real-world example, please refer to https://playground.seomastered.co/rendering/singlePage/static.

import React from 'react'
import { GetStaticProps, NextPage } from "next";
import { getCoffeeDescription } from '@/api/api';
import { sleep } from '@/utils/index'
import sleepingTime from '@/common/constants'

interface IProps {
	coffee: string;
}

const IStaticPage: NextPage<IProps> = props => {

	const { coffee } = props;

	return (
		<div>
			<h1>Static</h1>
			<p>This page is build during build time.</p>
			<pre>{coffee}</pre>
		</div>
	)
}


export const getStaticProps: GetStaticProps = async ctx => {

         // Data is fetched during build and the HTML is cached.

	const coffeeDescription = await getCoffeeDescription();
	const coffeeDescriptionText = JSON.stringify(coffeeDescription, null, 2)
	await sleep(sleepingTime);

	return {
		props: {
			coffee: coffeeDescriptionText
		},
	}
}

export default IStaticPage

Incremental Static Rendering (ISR):

In simple terms, ISR pages are pre-rendered pages that become static once a user visits them. You can specify after what interval the page is rebuilt (i.e. by specifying revalidate: 10). The disadvantage is that upon a new deployment, the very first request to this page is going to be slow. Once the page is built, it’s saved in the cache. All later requests to this page will be as fast as a request to a static page. After the revalidation period, the cache is invalidated and the page is rebuilt. The page speed of the user is not affected by this.

For a real-world example, please refer to https://playground.seomastered.co/rendering/singlePage/isr

import React from 'react'
import { GetStaticProps, NextPage } from "next";
import { getCoffeeDescription } from '@/api/api';
import { sleep } from '@/utils/index'
import sleepingTime from '@/common/constants'

interface IProps {
	coffee: string;
}

const ISRpage: NextPage<IProps> = props => {

	const { coffee } = props;

	return (
		<div>
			<h1>ISR</h1>
			<p>This page turns into a static page and is regenerated every N seconds.</p>
			<pre>{coffee}</pre>
		</div>
	)
}


export const getStaticProps: GetStaticProps = async ctx => {

	const coffeeDescription = await getCoffeeDescription();
	const coffeeDescriptionText = JSON.stringify(coffeeDescription, null, 2)
	await sleep(sleepingTime);

	return {
		props: {
			coffee: coffeeDescriptionText
		},
		revalidate: 60 * 60 // Regenerate this page every hour.
	}
}


export default ISRpage

ISR comes in handy in the following situations.

1.) If you run a large website and you want to have all pages statically generated. At the time of writing, Vercel build times out after 45 minutes of the building. You have to choose which pages you want to render statically and which pages are not. For example, you run a large e-commerce website.

2.) You would like the static page to be updated once in a while (e.g. every 10 minutes). This could be because new, fresh data is present. Simply specify the revalidate time and the site will be rebuilt.

HTML generation during run time

Server Side Generation (SSG):

The HTML is generated during run time. The HTML is generated when the user requests visits this page. A possible scenario might be a stock analysis website. Likely, you want the stock price to be real-time and not show a cached version from 10 minutes ago. SSR and CSR can be used for internal company dashboards. For these sites, SEO does not matter and it is more important to have real-time data compared to having a very fast loading time. SSR is also important after a user has logged in to a member’s area of a website (e.g. you log into your banking app) Likely, he will see unique data pertaining to his account and there is realistically no way to pre-render this site.

For a real-world example, please refer to https://playground.seomastered.co/rendering/singlePage/ssg

import React from 'react'
import { NextPage } from "next";
import { getCoffeeDescription } from '@/api/api';
import { sleep } from '@/utils/index'
import sleepingTime from '@/common/constants'

interface IProps {
	coffee: string;
}

const SSGpage: NextPage<IProps> = props => {

	const { coffee } = props;

	return (
		<>
			<div>
				<h1>SSG</h1>
				<p>Builds the HTML upon request.</p>
				<pre>{coffee}</pre>
			</div>
		</>
	)
}

export async function getServerSideProps() {
	const coffeeDescription = await getCoffeeDescription();
	const coffeeDescriptionText = JSON.stringify(coffeeDescription, null, 2)
	await sleep(sleepingTime);

	return {
		props: {
			coffee: coffeeDescriptionText
		}
	}

}


export default SSGpage

Client Side Generation (CSR):

Client Side Rendering pushes all the work to the browser. The user visits a page, gets served a blank page and then data is fetched and the site is built. CSR should not be used if you intend to get organic traffic to your website. Googlebot will find an empty page and nothing can be indexed.

For a real-world example, please refer to https://playground.seomastered.co/rendering/singlePage/csr

import React from 'react'
import { getCoffeeDescription } from '@/api/api';
import { sleep } from '@/utils/index'
import { NextPage } from 'next';
import { useState, useEffect } from 'react'
import sleepingTime from '@/common/constants'

const ClientSideRendering: NextPage = () => {
	const [coffeeData, setCoffeeData] = useState<string>()


	const getCoffeeData = async () => {
		const coffeeDescription = await getCoffeeDescription();
		const coffeeDescriptionText = JSON.stringify(coffeeDescription, null, 2)
		await sleep(sleepingTime);

		setCoffeeData(coffeeDescriptionText)
	}

	useEffect(() => {
		getCoffeeData()
	}, [])


	return (
		<>
			{coffeeData ?
				<div>
					<h1>Client Side Rendering</h1>
					<p>Loads the data after the page was rendered.</p>
					<pre>{coffeeData}</pre>
				</div>
				:
				<div>Loading...</div>
			}
		</>

	)
}

export default ClientSideRendering

Script: Asynchronously load third-party libraries

Next.Js makes it easy to asynchronously load javascript libraries and also define a loading strategy. To optimize your core web vitals score, the loading of most of the scripts should be deferred. Delaying the loading of some libraries can lead to small inaccuracies with regard to marketing attribution. You will have to make a judgment call on what is most important. In my eyes, I would take the increased organic traffic due to great Core Web Vital scores any day of the week. You should set the strategy to afterInteractive or lazyOnload in order to improve your Core Web Vitals score (LCP and FCP). More can be read here: https://nextjs.org/learn/seo/improve/third-party-scripts

import Script from 'next/script';

function IndexPage() {
  return (
    <div>
      <Scriptstrategy="afterInteractive"src="<https://www.googletagmanager.com/gtag/js?id=123>"/>
    </div>);
}

Code splitting: Only load the components you really need

Next.Js makes it easy to dynamically import components and libraries. If you have a page with a lot of content it is important to load this content only when it’s really necessary. Code splitting allows you to do so. You can dynamically import components as well as images. Make sure to not dynamically load the main text content of your website. For example, if you have run an e-commerce store selling iPhones, do not dynamically product descriptions.

Things you should avoid:

  • You should not dynamically load elements in the viewport because dynamic loading can be slow.
  • Use dynamic loading for the main text content (which might be outside of the viewport) of your website because it will likely never be loaded and thus not be indexed by Googlebot.
import dynamic from 'next/dynamic'

import component1 from '@/components/component1';
const component2 = dynamic(() => import('./component2'))
const component3 = dynamic(() => import('./component3'))

function YourComponent() {
  return (
    <>
			<component1 />
      <component2 />
      <component3 />
    <>
  )
}

Next.js Image Component optimizes loading images

Many websites are bloated with large images which delay the loading of the page content. Specifically, images are in a possibly wrong format and often they should be right-sized because they are too big for the screen (e.g. 6400 x 4000 pixels).

Next.JS has an image component that can solve this problem for you (NextJS Image Component). The image component can compress and resize an image on a remote server. Conveniently, images are also only loaded when in they are near or in the viewport. Your workflow can look like this:

  1. Upload all your original images to S3
  2. Use the <Image> component to load and optimize (crop, compress, convert to webp).
  3. Vercel serves (and cashes this version of your image) over its CND

Having website indexing issues?

Check out our blogs on the most common indexing issues and how to fix them. Fix your page indexing issues

Looking for an SEO Consultant?

Find the best SEO Consultant in Singapore (and worldwide). Best SEO Consultant

Is this you?

💸 You have been spending thousands of dollars on buying backlinks in the last months. Your rankings are only growing slowly.


❌You have been writing more and more blog posts, but traffic is not really growing.


😱You are stuck. Something is wrong with your website, but you don`t know what.



Let the SEO Copilot give you the clicks you deserve.