Reading Local Json Data With Next.js - part 5
Tags: react, nextjs, beginners, tutorial
Published: 2023-03-22 12:34:29

A new concept we need to be familiar with is [pre-rendering](https://nextjs.org/docs/basic-features/pages#pre-rendering).

_By default, Next.js pre-renders every page. This means that Next.js generates HTML for each page in advance, instead of having it all done by client-side JavaScript. Pre-rendering can result in better performance and SEO._

## Pre-rendering

Next.js allows choosing between two forms of pre-rendering: Static Generation and Server-side Rendering. The difference is in **when** it generates the HTML for a page.

### Static Generation (Recommended) 
The HTML is generated at build time (when you run `next build`) and will be reused on each request. Statically generated pages can be cached by CDN to boost performance.

- If the **content** depends on external data, you need to use `getStaticProps`.
- If the **paths** depend on external data you need `getStaticPaths`, usually in addition to `getStaticProps`.

### Server-side Rendering (SSR) 
The HTML is generated on each request. This might be a better choince when a page shows frequently updated data, and the page content changes on every request.

- You need to use `getServerSideProps`.

_Each generated HTML is associated with minimal JavaScript code necessary for that page. When a page is loaded by the browser, its JavaScript code runs and makes the page fully interactive. (This process is called hydration.)_

Hydration is used in [Angular](https://angular.io/guide/roadmap#explore-hydration-and-server-side-rendering-usability-improvements) and [React](https://react.dev/reference/react-dom/client/hydrateRoot) as well.

However, Next.js allows you to choose which pre-rendering form to use for each page.

Following the documentation, I will work on the example by using static generation.

If you application doesn't require external data, all _pages will automatically be statically generated when the app is built for production_.

This is not often the case in real life.

Next.js allows to fetch data at build time by using exporting an async function called `getStaticProps`.

Inside the  `getStaticProps` function we can make asynchronous operations like fetching data from a server.

The documentation proposes an example using markdown files but since json data is more common, I will show how to retrieve data from a local json file before fetching it from a server.

## Using Static Generation To Read A Local Json File

While we could store a json file in the public folder, that is not very safe. So we create a new folder at the root level and we call it json.

### Set Up Json Data

Create a folder at the root level and call it json. 
Inside the json folder, create a file called data.json in which we can copy-paste a [list of users from jsonplaceholder](https://jsonplaceholder.typicode.com/users).

![json.data file](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6j4x1jhp6yf2fxlngv1l.png)

### Read Json Data

Create another folder at the root level of the application and call it lib. Inside the lib folder create a file and name it localdata.js.

In localdata.js we are going to create a utily function to read data from the json file. 

Inside localdata.js we can add the following code:

```
import fsPromises from 'fs/promises';
import path from 'path'

export async function getLocalData() {
  // Get the path of the json file
  const filePath = path.join(process.cwd(), 'json/data.json');
  // Read the json file
  const jsonData = await fsPromises.readFile(filePath);
  // Parse data as json
  const objectData = JSON.parse(jsonData);

  return objectData
}

```


### Display Data In Home
Now, we can display data in the Home component (index.js) by using the async `getStaticProps` function.

Here there are a few things to notice, first we need to import the utility function `getLocalData` in index.js.

```
//index.js
import Head from 'next/head';
import Layout, { siteTitle } from '../components/layout';
import utilStyles from '../styles/utils.module.css';
import Link from 'next/link';
import { getLocalData } from '../lib/localdata';

```

Second, we need to use the async function called `getStaticProps`.

Inside the  `getStaticProps` function we can make asynchronous operations like fetching data from a server.

```
// index.js

...
import { getLocalData } from '../lib/localdata';

export async function getStaticProps() {
  const localData = await getLocalData()

  return {
    props: { localData }
  }
}
```

Finally, we can pass localData as a prop to the Home component as follows:

```
// index.js 

...
export async function getStaticProps() {}

export default function Home({ localData }) { 
...

return (
    <>
      ...
      <Layout home>
        ...
        <section className={`${utilStyles.headingMd} ${utilStyles.padding1px}`}>
          <h2 className={utilStyles.headingLg}>Blog</h2>
          <ul className={utilStyles.list}>
            {localData.map(({ id, name, website }) => (
              <li className={utilStyles.listItem} key={id}>
                <b>{id} - {name}</b>

                <br />
                {website}
              </li>
            ))}
          </ul>
        </section>
        
      </Layout>
    </>
  )
}
```

Here is how my page looks like at the moment:


![Next.js Read Data From Local Json](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ub04cmnirxtv47tqu0om.png)

You can find another example [in this post on Medium](https://medium.com/javascript-in-plain-english/read-local-json-data-with-next-js-2a56c20eb651)

Otherwise, in the next post, we will read data from an API.