Introduction

Next.js is a popular framework used for building React applications that offer server-side rendering, automatic code-splitting, static exporting options, and easy production builds. It also relieves a lot of the general headaches involved with creating production-ready React applications.

In this article, we'll show you how to bootstrap a new Next.js web application, create your first page, retrieve and display data from an external API, add CSS styling, and prepare your application for deploying to production.

Through that process, you'll gain an understanding of how to use the framework.

Before you begin this guide you'll need to have Node.js and NPM installed on your local development machine. We created an installation guide if you need help getting Node.js and NPM installed on your machine.

Let's get started!

Table Of Contents

  1. Bootstrap a Next.js Application
  2. Create Your First Page
  3. Retrieve and Display Data From an External API
  4. Add CSS Styling
  5. Build Your Application for Production

Step 1 - Bootstrap a Next.js Application

To bootstrap a new Next.js application, we need to create a new project directory and install the required dependencies using NPM (Node.js Package Manager).

Open a new terminal window (Ctrl+Alt+T on Linux or Command+Space on Mac) and execute the command below to create a new project folder that will house your Next.js application (replace “your-project” with the name of your project):

    
      mkdir your-project
    
  

And cd into your new directory:

    
      cd your-project
    
  

Next, run this command to initiate a new Node.js application and create a package.json file in the root of your project:

    
      npm init -y
    
  

The npm init -y command creates a package.json file in the root of your project directory. The -y flag initializes the file with default values.

The package.json file will allow you to easily install and use NPM package dependencies in your project. It will also make things like sharing your project with other developers easier if you wish to do so in the future.

Check out the NPM documentation if you want to learn more about the contents of the package.json file.

Now that we have a package.json file created, we can install the required NPM package dependencies for your Next.js website.

To get started, we'll need the Next, React, and React-Dom NPM packages.

You can install all of them at once with this command:

    
      npm install --save next react react-dom
    
  

When those finish installing, you'll notice that a new node_modules directory was created in your project. This directory stores all of the installed dependencies for your project. If you look inside, you'll notice that the three NPM packages you installed and all of their sub-dependencies are in there.

Since we used the --save flag on your npm install command, the three dependencies will be listed in the "dependencies" section of your package.json file. In the future when you share your code with others, all of the packages in that list will be installed in the initial setup of the application or when the npm install command is run.

Now that we have your dependencies installed, we need a way to start your application.

Open your package.json file and replace the "scripts" section with this code:

    
      "scripts": {
        "dev": "next"
      },
    
  

The "dev" script is used to run the application when you're in development mode. This means your code will run with special error handling, hot-reloading, and other features that make the development process more pleasant.

Later on, we'll add more scripts to this section to handle the production versions of your application.

In your terminal, start the application in development mode with this command:

    
      npm run dev
    
  

You'll see an error when you execute that command:

    
      Couldn't find a `pages` directory. Please create one under the project root...
    
  

Next.js looked for a /pages directory that holds all the different paths for your website and threw an error when it didn't find one.

We'll fix that error in the next section by adding your application's first page.

Step 2 - Create Your First Page

To fix the error and get your website running, we need to create a new directory called /pages and add a page to it that Next.js can render.

First, create a /pages directory in the root of your project:

    
      mkdir pages
    
  

And cd into it with this command:

    
      cd pages
    
  

Then, add a new file called index.js with this command:

    
      touch index.js
    
  

The /pages directory will hold all of the pages for your website and the index.js file will serve as your homepage at the "/" URL path.

The name of each file in the /pages directory will match the URL path in the browser when your website is visited. For example, a file with the path /pages/articles.js will have a URL that displays as "/articles" in the browser. All of this is handled automatically by Next.js.

The /pages/index.js file is the only exception since it serves as the homepage at the "/" path.

We need to add some code to your /pages/index.js file to give Next.js something to render. Open /pages/index.js in your favorite text editor and add this code to the file:

    
      import React, { Component } from "react"

      export default class extends Component {
        render () {
          return (
            <div>Your Next.js App</div>
          )
        }
      }
    
  

The code above creates a React class component that will render "Your Next.js App" HTML in the browser and exports it with export default.

Save the changes to the file and restart your application with:

    
      npm run dev
    
  

Open your favorite browser and visit your website: http://localhost:3000.

You should see the text "Your Next.js App" displayed on the page.

Congratulations, you have now created a working Next.js website!

Step 3 - Retrieve and Display Data From an External API

One of the cool things about Next.js is the server-side rendering features that it provides. You can fetch and receive data from an external API before your web page renders.

To demonstrate this, we'll use a free and public API called RandomDog. Each time a request is made to their API, a random picture of a dog is returned.

Using this API, we'll update the Next.js page you just created to display the random dog picture each time the page is loaded.

We'll make requests with an NPM package called Isomorphic-Unfetch. This package is great for Next.js because it works in both client and server environments.

Install the NPM package to your project with this command:

    
      npm install --save isomorphic-unfetch
    
  

Once the installation process is finished, open the /pages/index.js file in your code editor.

First, make sure you import the isomorphic-unfetch NPM package you just installed at the top of the file:

    
      import fetch from "isomorphic-unfetch"
    
  

That will make the NPM package available for use in the page with the fetch variable.

Since we want to make the request to the RandomDog API before the page is loaded in the browser, we need to create a getInitialProps() function at the top of the React component of the page.

Here's what that function looks like:

    
      static async getInitialProps() {
        const res = await fetch("https://random.dog/woof.json?filter=mp4,webm")
        const data = await res.json()

        return {
          imageURL: data.url
        }
      }
    
  

The getInitialProps() function is asynchronous, which means that the React component will not be rendered until it has finished and returned its values via the return {} object.

Inside the getInitialProps() function, we first use fetch to make an HTTP request to the RandomDog API at the "https://random.dog/woof.json?filter=mp4,webm" URL.

That HTTP request will return JSON data that contains the file size and URL of the randomly generated image:

    
      { "fileSizeBytes": 79732, "url": "https://random.dog/474feef3-7ccf-4aff-94e5-9ad5a8b65a48.jpg" }
    
  

When the request finishes inside the getInitialProps() function, we hold the response in the data variable using the await res.json() method.

Then, we return the imageURL value from the function, which will be made available in the page as this.props.imageURL.

Now that our code is configured to retreive the random dog image each time the page loads, we need to update the React component to display the image inside the render() function:

    
      render () {
        return (
          <div className="homepage-wrapper">
            <h1>Random Dog Image</h1>
            <img src={this.props.imageURL} />
          </div>
        )
      }
    
  

Inside the render() function, we added some basic HTML code for a <h1> element and <img /> populated with the this.props.imageURL value we retrieved from the RandomDog API.

For your reference, the entire /pages/index.js file should look like this:

    
      import React, { Component } from "react"
      import fetch from "isomorphic-unfetch"

      export default class extends Component {
        static async getInitialProps() {
          const res = await fetch("https://random.dog/woof.json?filter=mp4,webm")
          const data = await res.json()

          return {
            imageURL: data.url
          }
        }

        render () {
          return (
            <div className="homepage-wrapper">
              <h1>Random Dog Image</h1>
              <img src={this.props.imageURL} />
            </div>
          )
        }
      }
    
  

Save the changes you made to the file and view the page in your browser: http://localhost:3000.

You should see the random dog image displayed on the page:

Random dog image on the Next.js page

Also, you'll notice that a new and random image is displayed each time you reload the page.

Awesome, you've now pulled data into your application from an external API!

Step 4 - Add CSS Styling

Next, we'll go over how to apply CSS styling to both your page and globally across your Next.js application. Luckily, Next.js has some built-in ways to do this.

First, let's create a directory where all your CSS files will be stored.

Navigate to the root destination of your Next.js application and create a new /styles directory:

    
      mkdir styles
    
  

Then, cd into the new directory and create a new index.css file:

    
      cd styles && touch index.css
    
  

Next, open the new /styles/index.css file in your editor and add this CSS code to the file:

    
      .homepage-wrapper {
        text-align: center;
        height: 100vh;
        margin: 0;
      }

      .homepage-wrapper h1 {
        padding: 20px;
        margin: 0;
        font-size: 22px;
      }

      .homepage-wrapper img {
        max-width: 100%;
      }
    
  

This CSS file contains some basic styling that centers everything on the page, adds some padding and font sizing to the title, and sets a maximum width to the dog image.

Now that we have a CSS file created, we need to create a new /pages/_app.js file where we will import the CSS file we just created.

First, create the _app.js file inside the /pages directory:

    
      cd pages && touch _app.js
    
  

And add this code to it via your editor:

    
      import "../styles/index.css"

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

The styles file (/styles/index.css) will apply to all pages and components inside your application. Since these stylesheets are globally applied, you may only import CSS files inside the /pages/_app.js file to avoid conflicts.

In development, these files will be hot-reloaded as you make edits to them. In production, all CSS files imported into this file will be automatically concatenated into a single minified .css file.

Save the changes you made to your files and view your Next.js application in your browser: http://localhost:3000

Random dog image on the Next.js page with styles applied

You should see that the new CSS styles have taken effect on the page.

If you're looking for additional ways to apply CSS styling to your Next.js application, check out this section of the Next.js documentation.

In the next part of this article, we'll go over how to prepare your application for deployment.

Step 5 - Build Your Application for Production

Next.js makes the deployment process easy and pain-free.

First, we need to add both a "build" and "start" script to the package.json file.

Open your package.json file and make the "scripts" section look like this:

    
      "scripts": {
        "dev": "next",
        "build": "next build",
        "start": "next start"
      },
    
  

The "build" script will create a compiled and optimized version of your application inside a /.next directory in your project. And the "start" script is how you start the code in the /.next directory when your application is in a production environment.

To build the application, run the command:

    
      npm run build
    
  

It will take a few moments to finish running.

When it's done, notice that a new directory called /.next was created. There are a lot of different directories and files that Next.js adds to that directory. For this tutorial, all you need to know is that it's an optimized version of the code you have been running in development mode.

To start the application in production mode and run the code inside the /.next directory, run this command:

    
      npm start
    
  

The production-ready version of your website should now be running at http://localhost:3000.

When you deploy your application to a production environment, this is how you run an optimized version of your website.

That was the last step in this article.

Conclusion

You have now finished creating a website with Next.js and React. You should now be able to:

  • Bootstrap a new Next.js application.
  • Create new pages in a Next.js application.
  • Fetch data from an external API and display it on a Next.js page.
  • Add CSS styling to your pages and components.
  • Build and run a Next.js application in production mode.

The website we built in this tutorial can be greatly expanded. You can add more pages to the /pages directory, fetch data from another API you or someone else has built, and/or deploy the application to a server and make it accessible to the world.

These are just a few examples of what you could do to enhance your Next.js application.

If you're looking for something cool to build using the Next.js framework, we have a free course that walks you through building a coding blog with a custom CMS (Content Management System).

In the course, additional things like connecting your Next.js application to a REST API, getting your website indexed by search engines, and configuring Google Analytics are covered.

Thanks for reading and happy coding!