DEV Community

Michael Burrows
Michael Burrows

Posted on • Originally published at michaelburrows.xyz

Create and deploy a dynamic website with Next.js

Next.js 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.

Alt Text

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:

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,
    },
  };
}
Enter fullscreen mode Exit fullscreen mode

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:

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>
  );
}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

[name] provides a dynamic route 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:

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,
    },
  };
}
Enter fullscreen mode Exit fullscreen mode

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

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>
  );
}
Enter fullscreen mode Exit fullscreen mode

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";
Enter fullscreen mode Exit fullscreen mode

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

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

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:

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

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:

.team {
  max-width: 400px;
  margin: auto;
}
.team img {
  max-width: 100%;
  display: block;
}
.team ul {
  padding-left: 1rem;
}
Enter fullscreen mode Exit fullscreen mode

Adding <title> tags

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

import Head from "next/head";
Enter fullscreen mode Exit fullscreen mode

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

...
<div className="teams">
      <Head>
        <title>NBA Teams</title>
      </Head>
      {teams.map((team) => {
...
Enter fullscreen mode Exit fullscreen mode

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.

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 then install the Vercel CLI with the following command:

npm i -g vercel
Enter fullscreen mode Exit fullscreen mode

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/.

Top comments (1)

Collapse
 
ashishagarwal profile image
Ashish Agarwal

I just want to ask you, your website isn't dynamic as I know, it fetches data from API at build time and is deployed statically.

If you don't believe me, try it out yourself: make a simple project that shows total visit and every page load increase 1 visit, I guess.