next.js-tutorial

Next.js Pre-Rendering

Instead of relying on client-side JavaScript to generate HTML for each page, Next.js generates it in advance. In a Next.j app, pre-rendering is completed by default.

What’s the point of pre-rendering?

It improves performance since we have to fetch data from an external API and then render the UI in a React app, which means we have to wait for the JavaScript to be executed. The HTML for a pre-rendered page is already generated, so it loads faster.

It helps with Search Engine Optimization (SEO), When a search engine accesses your page in a React app, it simply sees a div tag with the id root. When a search engine encounters a pre-rendered page, however, all of the content is present in the source code, which aids in indexing.

Next.js Supports Two Forms of Pre-Rendering

1. Static generation without data

HTML pages are generated at build time in a static generation. When we develop the program, we generate the HTML with all of the data that makes up the content of the web pages in advance. A CDN can build pages once and serve them to clients virtually instantly. Article sites, e-commerce product pages, and documentation pages are the most common places to find it.

Next.js, as we all know, pre-renders every page in-app by default. When we develop our program, the HTML for each page will be produced statically.

How to create

Getting started is as simple as running a single line in the terminal.

Open up the directory you’d like to create your project in and run:

npx create-next-app my-static-nextjs-app

After the installation is complete, you can navigate to your new project directory:

cd my-static-nextjs-app

Once there, start your development server:

npm run dev

And once the server is ready, you can open up http://localhost:3000 in your browser where you can now see your new Next.js app!

2. Static generation with data

When we export a page component in Next.js, we may also export getStaticProps, an async method. If we export this function, it will execute in production at build time, and we can gather external data and deliver it as props to the page from within the function.

To make better use of Static site generation in Nextjs, let’s understand getStaticProps() function.

Using the getStaticProps() function:

This function is added to a Nextjs page so that it fetches data at build time.

To test things out, let’s create a project and create a new file airlines.js and a fake API https://api.instantwebtools.net/v1/airlines.

Open up the directory you’d like to create your project in and run:

npx create-next-app my-airlines-app

After the installation is complete, you can navigate to your new project directory:

cd my-airlines-app

Once there, start your development server:

npm run dev

And once the server is ready, you can open up http://localhost:3000 in your browser where you can now see your new Next.js app!

First of all, let’s make a simple Nextjs page called airlines.js inside our pages folder.

// airlines.js Page
function AirlineList({
  return <h1>Todos</h1>;
};

export default AirlineList;

let’s add the getStaticProps() function.

export default AirlineList;

// add getStaticProps() function
export async function getStaticProps() {}

The getStaticProps() function gives props needed for the component AirlineList to render things when Nextjs builds the page.

Note that we added the async keyword, this is needed so that Nextjs knows to prerender our airlines page at build time.

let’s write some code inside the getStaticProps() function.

// add getStaticProps() function
export async function getStaticProps() {
  const response = await fetch('https://api.instantwebtools.net/v1/airlines')
  const data = await response.json()

  return {
    props: {
      airlines: data
    }
  }
}

  • We can acquire the data for our AirlineList list from an API endpoint or a JSON file, for example.
  • Like way, we should return the airlines array from the props object.
return {
    props: {
      airlines: data
    }
};

Now let’s complete our AirlineList render code.

airlines.js

function AirlineList({
  airlines
}) {
  return (
    <>
      <h1> List of Airlines </h1> {
      airlines.map(airline => {
        return (
          <div key = {airline.id} >
            <p> {airline.name} </p>
            <p> {airline.country} </p>
            <p> {airline.slogan} </p>
          </div>
        )
      })
    } <
    />
  )
}

export default AirlineList

export async function getStaticProps() {
  const response = await fetch('https://api.instantwebtools.net/v1/airlines')
  const data = await response.json()

  return {
    props: {
      airlines: data
    }
  }
}

We are just mapping over our AirlineList array we received as a prop and rendering each airlines from the array inside an unordered list using the map() function in JavaScript.

The airlines prop is returned from getStaticProps() function.

Now run the app and navigate to http://localhost:3000/airlines.

3. Server-side generation

Pre-rendering is a type of SSR. When you need to fetch data per request and also when you need to fetch tailored data while keeping SEO in mind, the HTML is generated at request time.

Problems with static generation include the following:

  • We are unable to retrieve data at the time of the request. We get into the problem of stale data because we can’t fetch data per request.
  • When data that needs to be fetched is specific to a user, we don’t receive access to the incoming request.

Before we begin, we must first construct a server fake API with the json-server package, as well as a file called db.json that contains the list of things we will use in this section.

db.json

{
  "books": [
    {
      "id": 1,
      "title": "Things fall apart",
      "pages": 209,
      "languages": "English"
        },
    {
      "id": 2,
      "title": "Fairy tails",
      "pages": 784,
      "languages": "Danish"
        },
    {
      "id": 3,
      "title": "The book of Job",
      "pages": 176,
      "languages": "Hebrew"
        },
    {
      "id": 4,
      "title": "Pride and Prejudice",
      "pages": 443,
      "languages": "French"
        }
    ]
}

package.json

{
  "name": "pre-rendering",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint",
    "server-json": "json-server --watch db.json --port 2000"
  },
  "dependencies": {
    "json-server": "^0.16.3",
    "next": "12.0.7",
    "react": "17.0.2",
    "react-dom": "17.0.2"
  },
  "devDependencies": {
    "eslint": "8.4.0",
    "eslint-config-next": "12.0.7"
  }
}

Now let’s install the dependecies.

npm install

npm i json-server

To run type:

npm run server-json

Now you can see your server at the given link with the list of all the books in JSON format.

Now let’s make a book listing page that uses SSR to pre-render the content. Create a new folder, books, under our previously built project’s pre-rendering folder, and create index.js within the file.

To use SSR on a page, we must expose the getServerSideProps async function. When we export this function, the server will call it on every request, and we can use it to fetch external data and give it to the page as props.

The getServerSideProps method is never called from the client, thus we may write server-side code directly. Inside this, you can query a database.

books/index.js

function BooksList({
  books
}) {
  return (
    <>
      <h1>List of News Books</h1> {
      books.map(book => {
        return (
          <div key={book.id}>
            <h2>
              {book.id} {book.title} | {book.language}
            </h2>
            <hr />
          </div>
        )
      })
    } <
    />
  )
}

export default BooksList

export async function getServerSideProps() {
  const response = await fetch('http://localhost:2000/books')
  const data = await response.json()

  return {
    props: {
      books: data
    }
  }
}

Now open a new terminal window and start the development server with the following command:

npm run dev

Now navigate to localhost:3000/books.

RECOMMENDED ARTICLES





Leave a Reply

Your email address will not be published.