Next.js Beginner's Guide
Tags: javascript, react, beginners, tutorial
Published: 2021-06-02 20:57:14

---
title: Next.js Beginner's Guide
published: true
description: 
tags: javascript, react, beginner, tutorial
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rd3omc5vp71r5k9z69b4.png
---
Follow me!: <a href="https://twitter.com/EricTheCoder_" class="twitter-follow-button" data-show-count="false">Follow @EricTheCoder_</a><script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<hr>
<h2>What is Next.js?</h2>
It's a React frontend development web framework that enables functionality such as server-side rendering and static site generation.

<h3>Server-side rendering?</h3>
In a traditional React app the entire app is loaded and rendered on the client. Next.js allow the first page load to be rendered by the server, which is great for SEO and performance.

<h3>Next.js other benefits</h3>
- Easy page routing
- server Api routes
- Static site generation (like Gatsby)
- Easy Deployment

<h2>Create Next.js first project</h2>
To install and create a Next.js projet you can use the handy node npx command 'create-next-app my-app-name'
```
$ npx create-next-app my-app-name
```
Or with Tailwind CSS pre-configure
```
$ npx create-next-app -e with-tailwindcss my-app-name
```
This will create a folder and create all files, configs and everything you need to start a Next.js app.

Once the app is created you can launch it
```
$ cd your-app-name
$ npm run dev
```
This will launch your Next.js empty app. By default a welcome page is already created for you.

<h2>Pages and Routing</h2>
In Next.js to manage routes we dont have to use a routing library. 

Next.js routing is very easy to implement.

When you create a new Next.js app with the create-next-app command, the app create by default a folder name 'pages'

This 'pages' folder is your routes management. So every react components file in the folder will be treated as a specific route.

For example, if the folder is containing those files:
- index.js
- about.js
- blog.js

This file will automatically be converted in 3 routes:

- The index page localhost/index
- The about page localhost/about
- The blog page localhost/blog

As you can see the principle is very easy. 

Also, if you visit a route that dont exist like 'localhost/home' Next.js will automatically show a not found 404 page

Here an example of about.js page. Like you can see nothing is specified about the page. It is just a regular React functional component
```jsx
function AboutPage() {
    return (
        <div>
            <h1>About</h1>
        </div>
    )
}

export default AboutPage
```
<h3>Nested routes</h3>
How about nested routes like localhost/blog/contact?

To create nested routes you need to create a sub folder.

For example: pages/blog

Inside that folder you can create your 'contact.js' react component and that will create the page localhost/blog/contact

If you create a index.js file in that sub folder, Next.js will use that component to represent your root route. ex: localhost/blog will render pages/blog/index.js

If you create a file in pages/blog.js and another one under pages/blog/index.js. Both represent the same localhost/blog route. In that case Next.js will render only the blog.js file. 

What about dynamic routes where each blog post have it's own route:
- localhost/blog/my-first-blog
- localhost/blog/my-second-blog-post

In Next.js you can create a dynamic route using the brackets notation.

For example: pages/blog/[slug].js

Yes that look a bit weird to include brackets to a file name but that's the way.

If slug variable can be extract from the route using the useRoute hook.

Here a example of the [slug].js page
```jsx
import { useRouter } from 'next/router'

function PostPage() {
    const router = useRouter()
    return (
        <div>
            <h1>My post: {router.query.slug}</h1>
        </div>
    )
}

export default PostPage
```
That's a basic example. In a real app, the slug variable will be use to load the post file or lookup in a database for the corresponding post.

<h2>Routes links</h2>
Now that you created your first route. I guess you are wondering how to link pages to those routes? To do that you need 'next/link'

Here a example of the home page with a link to the about page:
```jsx
import Link from 'next/link'

export default function Home() {
  return (
    <div>
      <h1>Home</h1>
      <Link href="about">About</Link>
    </div>
  )
}
```
In the about page, if you want to create a link to come back to the home page. You can type:
```jsx
<Link href="/">Home</Link>
```
If you want to style the link you have to use this syntax:
```jsx
<Link href='/about'>
    <a className="text-blue-500">About this project</a>
</Link> 
```

<h2>Route redirect</h2>
What if you want to force a redirect to a specific page? For example on a click of a button? You can use 'router.push' for that:
```jsx
import Link from 'next/link'
import { useRouter } from 'next/router'

function About() {
  const router = useRouter()

  return (
    <div>
      <h1>About Page</h1>
      <p>This is the about page</p>
      <button onClick={() => router.push('/')}>Return to home</button>
    </div>
  )
}
```

<h2>Where you put components?</h2>
Often you will want to create a components or a layout file. For example a component to render navbar. 

Up until now we only have use the pages folder. What if you dont want your component to be a route page? You dont want user to go open page like: localhost/navbar 

That's what will append if you put Navbar.js component inside the pages folder. 

What to do in that case? Easy, you need to place all your 'not a page' components inside another folder.

By convention most Next.js use a folder name 'components' and this folder is created at the root folder of your apps.

So for example if you want to create a layout component you can do it in the new components folder: /components/Layout.js

That React component can be use anywhere in your app but will ne be reference as a route page.

<h2>Head compoment</h2>
Next.js server side render first page load. To do so it manipulate the html of you page. Including the header section.
 
To provide header section tag like title or meta you need to use the Next.js Head component.

Here's an example of a Layout component using the Head component.
```jsx
// components/Layout.js
import Head from 'next/head'
function Layout({title, keywords, description, children}) {
    return (
        <div>
            <Head>
                <title>{title}</title>
                <meta name='description' content={description}/>
                <meta name='keywords' content={keywords}/>
            </Head>
            {children}
        </div>
    )
}

export default Layout

Layout.defaultProps = {
    title: 'This is my app title',
    description: 'This is my app description',
    keywords: 'web, javascript, react, next'
}
```
<h2>Custom 404 not found page</h2>
It is possible to create a custom 404 not found page. You may want to personalize the message or include your own page layout. 

Create 404.js file in the pages folder.

Next.js will then automatically redirect to this page when a 404 is encounter. 

Here a example of a custom 404 page:
```jsx
// pages/404.js
import Layout from '../components/Layout'

function NotFoundPage() {
    return (
        <Layout>
            Sorry the page you are looking is no where to be found.        
        </Layout>
    )
}

export default NotFoundPage
```
<h2>Import shortcut alias</h2>
As your app grow more and more. Some components can be nested deep in your app folder structure.
```jsx
import Layout from '../../components/Layout'
``` 

It is possible to create a shortcut to help you save some key stroke and get a result like that:
```jsx
import Layout from '@/components/Layout'
```
The @ char is a shortcut syntax.

To create this shortcut and more you need to create a file name 'jsconfig.json' at the root of your app:
```json
// jsconfig.json
{
    "compilerOptions": {
        "baseUrl": ".",
        "paths": {
            "@/components/*": ["components/*"],
        }
    }
}
```

<h2>Server-side data fetching</h2>
Instead of fetching data on the client side, Next.js can
enables server-side rendering in a page and allows your to do initial data population, it means sending the page with the data already populated from the server. 

To implement that server-side data fetching you have 2 options:
1. Fetch data on each request
2. Fetch data only once at build time (static site)

<h3>Fetch data on each request<h3>
To server-side render on each request you need to use the getServerSideProps function.

You can add this function at the end of your component file:
```jsx
export async function getServerSideProps() {
  const res = await fetch(`http://server-name/api/items`)
  const items = await res.json()
  return {
    props: {items}, 
  }
}
```
If that function is present in your component file, Next.js will automatically fill you component props with the getServerSideProps object.

<h3>Fetch data at build time<h3>
To server-side render at build time you need to use the getStaticProps function.

You can add this function at the end of your component file:
```jsx
export async function getStaticProps() {
  const res = await fetch('http://server-name/api/items')
  const items = await res.json()
  return {
    props: {items}, 
  }
}
```

You may also want to fetch data at build time but for a dynamic path (ex. /posts/my-first-post)

Let asume we have a page name posts/[slug].js

That will give you a routes of posts/my-first-post, posts/my-second-blog, etc.

In that situation you can use getStaticPaths to create all those sub routes at build time

```javascript
export async function getStaticPaths() {
    const res = await fetch(`${API_URL}/posts`)
    const posts = await res.json()
    const paths = posts.map(post => ({params: {slug: post.slug}}))
    return {
        paths,
        fallback: true,
    }
}
export async function getStaticProps({params: {slug}}) {
    const res = await fetch(`${API_URL}/posts?slug=${slug}`)
    const posts = await res.json()
    return {
        props: {
            post: posts[0]
        }
    }
}
``` 

<h2>Image optimization</h2>
Next.js has a built-in Image Component and Automatic Image Optimization.

The Next.js Image Component, next/image, is an extension of the HTML <img> element, evolved for the modern web.

Images are lazy loaded by default. That means your page speed isn't penalized for images outside the viewport. Images load as they are scrolled into viewport.

First import the Image Component:
```jsx
import Image from 'next/image'
```
Use it in your component:
```jsx
<Image
  src="/image.png"
  alt="Picture of the author"
  width={500}
  height={500}
/>
```
If you want to know more about Next.js Image component you can read the official documentation: https://nextjs.org/docs/api-reference/next/image


<h2>Conclusion</h2>
That's it for today. I still have a lot of posts coming about React so if you want to be sure to miss nothing click follow me!

Follow me!: <a href="https://twitter.com/EricTheCoder_" class="twitter-follow-button" data-show-count="false">Follow @EricTheCoder_</a><script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<hr>