Back

Pre-rendering Techniques in Next.js for React

Pre-rendering Techniques in Next.js for React

The Next.js framework brings friendly and welcome solutions to some problems in the React framework. Some solutions include out-of-the-box support for routing, SEO optimization, etc., and in particular, different pre-rendering techniques. By pre-rendering, we mean the process whereby the structure of a loaded page is first displayed before the final content is displayed. Pre-rendering shows a static snapshot of a page immediately, which can be advantageous for displaying information to search engines on page load without requiring them to render anything.

Next.js automatically pre-renders every page in an application. Next.js generates HTML for every page in advance instead of having it done on the server. The Javascript is loaded after the HTML, thereby making the page interactive. This has immediate advantages:

  • Pre-rendering improves application performance: In a React application, there is usually a user wait time where the Javascript gets loaded, and then fetching occurs before the UI gets rendered. The user can be pacified by a loading spinner or a text showing on the screen to indicate loading in progress but the wait time is still there.
  • The HTML is already generated and loads faster in a Next.js application that pre-renders pages on default. This virtually eliminates any user wait time.
  • Pre-rendering helps with SEO: Search Engine Optimization is a process of improving your site and ranking it higher in search results. A pre-rendered page has all its content in the source code, which helps index that page and leads to better search rankings.

This article will look at different pre-rendering techniques in Next.js and then compare two of those techniques, their pros and cons, use cases, and how to implement them in a Next.js application.

Different pre-rendering techniques in Next.js

This section will cover some different pre-rendering techniques that are available in Next.js.

  • Client Side Rendering (CSR): Client-side rendering is the default and most common way of rendering Next.js applications. Next.js renders your page this if you don’t set up a getServerSideProps function. CSR is a process whereby the server renders an empty page referencing Javascript files, and the browser downloads the page with the Javascript references and then builds the page. — Server Side Rendering (SSR): Server-side rendering, also known as dynamic rendering, is the process whereby the page is pre-rendered on the server and then sent back upon a user’s request. Next.js provides the getServerSideProps function for SSR. This function gets called whenever a request is made to the server for a page.
  • Static Site Generation (SSG): Static site generation is a process whereby a Next.js application is converted to an HTML file and then sent to the client at build time. SSG creates some static paths based on the required data, and at build time, the paths are rendered out into static pages, which load very fast on the client side. In particular, Next.js provides two functions for data fetching with SSG.
    • getStaticProps: The page gets pre-rendered, and all data needed is passed on to the app components as props at build time.
    • getStaticPaths: This function creates a list of pages to be pre-rendered during the build process. This is important because the function allows you to create dynamic routes for data.

In the following sections, we’ll discuss the pros and cons of SSG and SSR in Next applications. We will also look at how to implement them in a Next.js application.

Note: This article focuses on comparing SSG and SSR in Next applications; therefore, the pros and cons of CSR won’t be covered.

SSR

The advantages of SSR are clear:

  • Immediate page availability: Server-side rendered pages are available immediately from the first page, and this helps for slower connections
  • SEO friendly: Web crawlers will see all of the data from the application because all metadata has been resolved into HTML when the page is fetched, which is excellent for SEO.

There are also disadvantages to SSR:

  • Pages are rendered twice, on the server and the client. This takes time, so the initial HTML sent to the client could be delayed.
  • There might be some latency on the server when the application is loading due to many users trying to access the application.

Implementing SSR is not complex:

export async function getServerSideProps() {
    const res = await fetch(`fetch something from somewhere hopefully`)
    const data = await res.json()

    // Pass data to the page via props
    return { props: { data } }
}

In the code block above, we use the getServerSideProps function to signify to our Next.js application that we want the data retrieved from the server and passed as props to the application component.

Open Source Session Replay

OpenReplay is an open-source, session replay suite that lets you see what users do on your web app, helping you troubleshoot issues faster. OpenReplay is self-hosted for full control over your data.

replayer.png

Start enjoying your debugging experience - start using OpenReplay for free.

SSG

SSG has advantages:

  • SEO friendly: Sites built with SSG are optimized for SEO. This is because the HTML gets generated before being sent to the client and search engines like HTML.
  • Immediate page availability: Statically generated pages are always available as they are created immediately and don’t need additional data fetching.
  • Fast to serve: Statically generated pages are very fast to serve

It also has some disadvantages:

  • Long build time: If your site is large and complicated, build times can be quite long.
  • Since data is only fetched once during the build process, you cannot refetch or reload data on the go.
  • UI compatibility issues can occur if there is a need for a window or document because Node doesn’t have that.

There are two ways to implement static site generation in a Next.js application. The first way is when we need a static page that doesn’t rely on external data, and the second way is when we need dynamic routes for our pages.

Let’s take a blog, for example. Each blog has a page to display all the fetched blog posts and another for displaying a specific post. The first way is to create our static page and load some assets. We do this using the getStaticProps function.

export default function Blog({ posts }) {
    return (
    <div>
    {posts.map((post) => (
    <h1>{post.title}</h1>
    ))}
    </div>
    )
}

expo
    const data = await fetch('fetch something from somewhere hopefully')
    const posts = await data.json()

    return {
    props: {
    posts,
    },
    }
}

In the code above, we pass our data as props to our component. The page gets generated into a static page at build time which is then served to the client upon request.

The second method, which involves creating dynamic routes, uses the getStaticPaths function. To do this, you create a [id].jsx page and then paste the code below.

export async function getStaticPaths() {
    const data = await fetch('fetch something from somewhere hopefully')
    const posts = await data.json()
    const slugs = posts.map((post) => ({
    params: { id: post.id },
    }))

    return { slugs }
}

When to use them

Server-side rendering is recommended for applications where you have to update data from external sources frequently. Some examples of such applications include an e-commerce site or a page that renders search results.

Static site generation is excellent for applications where SEO is a major requirement and your application’s dataset doesn’t change often. Some examples include blogs, portfolio sites, etc.

Conclusion

This article has taken a look at some different pre-rendering techniques available in Next.js, their pros, cons, use cases, and how to implement them in your application; do consider them for your own work!

A TIP FROM THE EDITOR: If you want to consider something new, take a look at our An Alternative to Next.JS? - Everything You Need to Know About RemixJS article.