Create and deploy a dynamic website with Next.js
Tags: react, nextjs, tutorial, webdev
Published: 2020-08-25 06:14:43

[Next.js](https://nextjs.org/) is a framework for developing production grade React applications and websites that scale.

In this tutorial we’ll be creating a Next.js website that fetches data about NBA teams from the [SportsDB API](https://thesportsdb.com/).

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/syduy3ewk7kdmm9lnsks.png)

## Create a Next.js project

We’ll start by running `npx create-next-app` the easiest way to get started with Next.js.

Once finished `run npm run dev` and a local server running at http://localhost:3000 will be started.

## Homepage

Open the `pages/index.js` file and remove all the placeholder code.

With a clean starting point we’ll make an API request to return a list of all the teams in the NBA:

```javascript
const endpoint = "https://www.thesportsdb.com/api/v1/json/1/search_all_teams.php?l=nba";
export async function getServerSideProps() {
  const res = await fetch(endpoint);
  const data = await res.json();
  return {
    props: {
      data,
    },
  };
}
```

Next.js will pre-render this page on each request using the data returned by `getServerSideProps`.

We can then pass `data` to a `Home()` function that will output the team names and logos:

```javascript
export default function Home({ data }) {
  const { teams = [] } = data;
  return (
    <div className="teams">     
      {teams.map((team) => {
        const { idTeam, strTeam, strTeamBadge } = team;
        return (   
          <div key={idTeam}>      
            <img src={strTeamBadge} width="100" />
            <p>{strTeam}</p>
          </div>  
        );
      })}
    </div>
  );
}
```

## Team pages

Next we’ll create the individual team pages, we’ll link the homepage with these pages later in the tutorial.

Inside the pages folder create a `team` folder with a `[name]` subfolder and a `index.js` file:

```
|- pages
  |- team
    |- [name]
     - index.js
```

`[name]` provides a [dynamic route](https://nextjs.org/docs/routing/dynamic-routes) so we can pass the team name via the URL e.g: `/team/Brooklyn%20Nets`

In `team/[name]/index.js` add the following to search the API for the team name:

```javascript
const endpoint = "https://www.thesportsdb.com/api/v1/json/1/searchteams.php?t=";
export async function getServerSideProps({ query }) {
  const { name } = query;
  const res = await fetch(`${endpoint}${name}`);
  const data = await res.json();
  return {
    props: {
      data,
    },
  };
}
```

Similar to the homepage we’ll grab the data and output it into the page by creating a `Team()` function:

```javascript
export default function Team({ data }) {
  console.log(data);
  const {
    strTeam,
    strStadium,
    strStadiumThumb,
    strFacebook,
    strInstagram,
    strTwitter,
  } = data.teams[0]; 
  return (
    <div className="team">
      <h1>{strTeam}</h1>
      <h3>Stadium</h3>
      <p>{strStadium}</p>
      <img src={strStadiumThumb} width="400" />
      <h3>Social</h3>
      <ul>
        <li><a href={strFacebook}>Facebook</a></li>
        <li><a href={strInstagram}>Instagram</a></li>
        <li><a href={strTwitter}>Twitter</a></li>
      </ul>
    </div>
  );
}
```

This will be enough data for this tutorial but if you view the `console.log` you’ll see the full set of data available.

## Linking homepage to the team pages

Now we need to add the hyperlink that links the homepage to the individual team pages.

Re-open `pages/index.js` and import the Next.js `Link` component by adding the following to the first line:

```
import Link from "next/link";
```

Edit the `return` to include the component linking it the team page using the team name as a query string:

```javascript
return (
  <span key={idTeam}>
    <Link href="/team/[name]" as={`/team/${strTeam}`}>
      <a>
        <img src={strTeamBadge} width="100" />
        <p>{strTeam}</p>
      </a>
    </Link>
  </span>
);
```

## Adding styling

With the data in place let’s now give our website some basic CSS.

The application is already loading a `global.css` file so let’s add our CSS there:

```css
.teams {
  padding: 5%;
  text-align: center;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  grid-gap: 1rem;
}
```

This creates a responsive grid layout of the team logos on the homepage.

For the individual team pages let’s center align the content and restrict the maximum width:

```css
.team {
  max-width: 400px;
  margin: auto;
}
.team img {
  max-width: 100%;
  display: block;
}
.team ul {
  padding-left: 1rem;
}
```

## Adding `<title>` tags

Currently the `<title>` tag don’t exist so lets import the Next.js `Head` component at the top of `index.js`:

```javascript
import Head from "next/head";
```

Then insert the component as the first element in the return `<div>` with a title tag:

```javascript
...
<div className="teams">
      <Head>
        <title>NBA Teams</title>
      </Head>
      {teams.map((team) => {
...
```

You now have a website that allows you to select a team and get some basic info about them.

It could be further expanded upon by loading data from these additional [SportsDB endpoints](https://thesportsdb.com/api.php).

## Deploying to Vercel

Because Next.js was created and maintained by Vercel they make it simple to deploy Next.js applications.

Create a free account [https://vercel.com/signup](https://vercel.com/signup) then install the Vercel CLI with the following command:

```
npm i -g vercel
```

Now run the `vercel` command and you’ll be asked to verify your email address.

Once verified run `vercel` again and follow the prompts to deploy the site to a Vercel sub domain.

Here’s the completed website deployed to Vercel – [https://nbateams.vercel.app/](https://nbateams.vercel.app/).