Beginner's Guide to NextJS
Tags: javascript, webdev, nextjs, react
Published: 2022-05-19 15:43:27

## What is NextJS ?

NextJS is an open-source web development framework built on top of Node.js enabling React-based web application functionalities.
NextJS was first released as an open-source project on GitHub on October 25, 2016. Currently, NextJS is owned by Vercel, formerly ZEIT.

NextJS is Full-stack because it facilitates writing client-side code and server-side code, and Production-ready because it provides features that are missing in react library like routing, etc. NextJS offers a ton of features for ease of a developer which we will discuss later in this blog.

## How to start a NextJs project?

You can start a NextJs project with run following CLI commands which sets up everything automatically for you.

```bash
npx create-next-app my-app
# or
yarn create next-app
# or
pnpm create next-app
```

After creating a nextJs project you will get folders public, pages, and styles along with next.config.js file. let's explore them one by one.

## Next Config File

next.config.js is a regular Node.js module, not a JSON file. It gets used by the NextJS server and build phases, and it's not included in the browser build.

Take a look at the following next.config.js example:

```javascript
const nextConfig = {
  /* config options here */
}

module.exports = nextConfig
```

The commented lines are the place where you can put the configs allowed by next.config.js, which are defined in this file.
However, none of the configs are required, and it's not necessary to understand what each config does.

Read more about next config at official documents [here](https://nextjs.org/docs/api-reference/next.config.js/introduction)

## Static File Serving

NextJS can serve static files, like images, under a folder called public in the root directory. Files inside the public can then be referenced by your code starting from the base URL (`/`).


For example, if you add an image to `public/me.png`, the following code will access the image:

```jsx
function Avatar() {
  return <Image src="/me.png" alt="me" width="64" height="64" />
}

export default Avatar
```
## Routing

In NextJS, a page is a React Component exported from a .js, .jsx, .ts, or .tsx file in the pages directory. Each page is associated with a route based on its file name.

Example: If you create `pages/about.js` that exports a React component like below, it will be accessible at `/about`.

```javascript
function About() {
  return <div>About</div>
}

export default About
```

There is another way to use routing in NextJS. You can create a folder with the name `about` and create a file name `index`. Then also you can access path `/about`.

### Dynamic Routes

NextJS supports pages with dynamic routes. For example, if you create a file called `pages/posts/[id].js`, then it will be accessible at `posts/1`, `posts/2`, etc. square bracket provides a dynamic name.

### Nested Routes

let's say there are 3 routes you want to access `/account`, `/account/profile`, and `/account/setting` you can also achieve this in NextJS very easily.

In the pages directory creates a folder name `account` and then creates 3 files inside it with named viz. `index`, `profile`, and `setting`. The index file will be accessible at `/account` path, profile file will be accessible at `/account/profile`, and the setting file will be accessible at `/account/setting`.

You can achieve this for deeply nested routes too. Isn't it amazing? This routing feature is my favorite in Next Js. 

### next/router

This is the extension of nextJS routing features. NextJs provides a `useRouter` hook to navigate conditionally.

```javascript
import { useRouter } from 'next/router'

function ActiveLink({ children, href }) {
  const router = useRouter()
  const style = {
    marginRight: 10,
    color: router.asPath === href ? 'red' : 'black',
  }

  const handleClick = (e) => {
    e.preventDefault()
    router.push(href)
  }

  return (
    <a href={href} onClick={handleClick} style={style}>
      {children}
    </a>
  )
}

export default ActiveLink
```

### Router Object

The router object returned by both useRouter and withRouter. You can read more in-depth about this router object in NextJS official documentation. [Read here](https://nextjs.org/docs/api-reference/next/router#router-object)

### next/link

Client-side transitions between routes can be enabled via the Link component exported by next/link.

For an example, consider a pages directory with the following files:
`pages/index.js`
`pages/about.js`
`pages/blog/[slug].js`

We can have a link to each of these pages like so:

```javascript
import Link from 'next/link'

function Home() {
  return (
    <ul>
      <li>
        <Link href="/">
          <a>Home</a>
        </Link>
      </li>
      <li>
        <Link href="/about">
          <a>About Us</a>
        </Link>
      </li>
      <li>
        <Link href="/blog/hello-world">
          <a>Blog Post</a>
        </Link>
      </li>
    </ul>
  )
}

export default Home
```

## Styling

To add a global stylesheet to your application, import the CSS file within `pages/_app.js`.
For example, consider the following stylesheet named `styles.css`:

```css
body {
  font-family: sans-serif;
  padding: 20px 20px 60px;
  max-width: 680px;
  margin: 0 auto;
}
```

Create a `pages/_app.js` file if not already present. Then, import the `styles.css` file.

```javascript
import '../styles.css'

// This default export is required in a new `pages/_app.js` file.
export default function MyApp({ Component, pageProps }) {
  return <Component {...pageProps} />
}
```

If you don't want to use CSS styling globally. You can use CSS Modules which is in-built in nextJS and helps you to keep CSS styling locally.

## Client-side and Server-side Rendering

Client-side rendering allows developers to make their websites entirely rendered in the browser with JavaScript. Instead of having a different HTML page per route, a client-side rendered website creates each route dynamically directly in the browser. This approach spread once JS frameworks made it easy to take.

Client-side rendering manages the routing dynamically without refreshing the page every time a user requests a different route. But server-side rendering can display a fully populated page on the first load for any route of the website, whereas client-side rendering displays a blank page first.

Though NextJS is based on react library it facilitates client-side rendering but it offers server-side rendering too.

## Benefits of Server Side Rendering:

- A server-side rendered application enables pages to load faster, improving the user experience.
- When rendering server-side, search engines can easily index and crawl content because the content can be rendered before the page is loaded, which is ideal for SEO. 
- Webpages are correctly indexed because web browsers prioritize web pages with faster load times.
- Rendering server-side helps efficiently load webpages for users with a slow internet connection or outdated devices.

## Server-Side Rendering in NextJS

There are two ways to use server-side rendering in nextJS. Either page can be served static generated way or generated on the fly. For these features it offers two functions: *getServerSideProps* and *getStaticProps*.

### getServerSideProps Function

If you export a function called getServerSideProps (Server-Side Rendering) from a page, Next.js will pre-render this page on each request using the data returned by getServerSideProps.

```javascript
export async function getServerSideProps(context) {
  return {
    props: {}, // will be passed to the page component as props
  }
}
```

It returns props which you can in react component.
You should use getServerSideProps only if you need to render a page whose data must be fetched at the requested time. 

### getStaticProps Function
 
If you export a function called getStaticProps (Static Site Generation) from a page, NextJS will pre-render this page at build time using the props returned by getStaticProps.

```javascript
export async function getStaticProps(context) {
  return {
    props: {}, // will be passed to the page component as props
  }
}
```

You should use getStaticProps if The data required to render the page is available at build time ahead of a user’s request.

### getStaticPaths Function

If a page has Dynamic Routes and uses *getStaticProps*, it needs to define a list of paths to be statically generated during build time.

When you export a function called getStaticPaths (Static Site Generation) from a page that uses dynamic routes, NextJS will statically pre-render all the paths specified by *getStaticPaths*.

```javascript
export async function getStaticPaths() {
  return {
    paths: [
      { params: { ... } }
    ],
    fallback: true // false or 'blocking'
  };
}
```

This is the overview of these special functions which nextJS provides. For in-depth information read at NextJS official documentation.

## Next API

We have seen client-side routing and server-side rendering functionality with NextJS. If you want to create RestFul API then you don't need to create it separately. NextJs provides this functionality as an in-built feature. There is an API folder available inside the pages folder where you can create RESTFul API. Every file you create with `.js/.jsx/.ts/.tsx` extension works as an endpoint to which you can send API calls and connect to the backend. Node environment is available in the API folder so you use the environmental variable with using the process object.

For example, the following API route `pages/api/user.js` returns a json response with a status code of 200:

```javascript
export default function handler(req, res) {
  res.status(200).json({ name: 'John Doe' })
}
```

Though so many features left like next/Image, next/head, eslint and typescript support, optimization etc. which NextJS offers for website development but this blog is about NextJS basics. You can explore more about NextJS in their official document.

---