DEV Community

Cover image for Let’s build and deploy a Full Stack Next.js App: Part 3
Musole Masu
Musole Masu

Posted on

Let’s build and deploy a Full Stack Next.js App: Part 3

Here is the last part of this tutorial series. In this part we are going to fetch data from the Mongo DB and to deploy the application on Vercel.

In case you missed part 2 of this tutorial series, click HERE to catch up.

1. Let's fetch from Mongo

Note: Now, You might have a different IP address than what you put on the Network Access section in your mongo cluster. So make sure to update.

Previously, we successfully connected our App to a Mongo DB database and successfully stored data in. Open the terminal, in the project directory run $ npm run dev and let's proceed with the fetch.

1.1 Fetch at build time

Next.js provides two methods of pre-rendering. You can preload elements on pages by exporting the getStaticProps or the getServerSideProps functions on your pages. For this tutorial we will go with getStaticProps, since we will not make a lot of changes with the data and also we will not have too many requests.

current project directory
This should be your project directory. On "/pages", open the "index.js" file and replace the existing code with the code below:

import MealList from "../components/MealList";
import { MongoClient } from "mongodb";
const HomePage = (props) => {
  return <MealList meals={props.mealList} />;
};
export async function getStaticProps() {
  const DATABASE_NAME = "FoodApp";
  const DATABASE_PASSWORD = "1234567H";

  const client = await MongoClient.connect(
    `mongodb+srv://masu:${DATABASE_PASSWORD}@foodapp.0tpop.mongodb.net/${DATABASE_NAME}?retryWrites=true&w=majority`
  );
  const db = client.db();
  const mealsCollection = db.collection("meals");
  const meals = await mealsCollection.find().toArray();

  client.close();

  return {
    props: {
      mealList: meals.map((meal) => ({
        id: meal._id.toString(),
        name: meal.name,
        image: meal.image_path,
        dish: meal.dishes,
        chef: meal.chef,
      })),
    },
  };
}
export default HomePage;

Enter fullscreen mode Exit fullscreen mode

Warning: Replace const DATABASE_NAME and const DATABASE_PASSWORD with the value you put early in part 2 of the tutorial.

In the code above, we did the following:

  • Imported MongoClient,
  • Imported MealList react component,
  • Created a function component "HomePage" that returns the MealList component imported earlier,
  • Exported async getStaticProps function, where we connected the app to the Mongo DB database using the MongoClient and fetched meals from the database.
  • async getStaticProps function returns a props which the fetched meals values are assigned to, then passed to the "HomePage" component as a props,
  • The "HomePage" function component passes its props to the "MealList" component.

1.2 Let's make dynamic components

We are still displaying a static page, let's use the data passed with the props in the " MealList" component; to have a dynamic page.
In the "/components" directory, open the "MealList.js" file and replace all with the below:

import MealItem from "./MealItem";
const MealList = (props) => {
  return (
    <div className="flex flex-wrap">
      {props.meals.map((meal) => (
        <MealItem meal={meal} key={meal.id} />
      ))}
    </div>
  );
};
export default MealList;
Enter fullscreen mode Exit fullscreen mode

Still in the same directory, open the "MealItem.js" file where you put these:

const MealItem = ({ meal }) => {
  return (
    <div className="w-1/4 p-8 shadow-lg rounded-lg bg-yellow-50">
      <img src={meal.image} className="w-auto h-auto" alt="Chicken Salad" />
      <div className="text-center py-2">
        <h3 className="text-xl font-normal">
          {meal.name}
          <span className="px-3 font-light text-yellow-500">
            ({meal.dish} dishes)
          </span>
        </h3>
        <p className="text-gray-500 text-base">{meal.chef}</p>
        <button className="bg-yellow-500 px-4 py-2 rounded-lg text-gray-50 font-medium mt-2">
          Details
        </button>
      </div>
    </div>
  );
};
export default MealItem;
Enter fullscreen mode Exit fullscreen mode

By this moment, if your command $ npm run dev is still running, the home page will be served with data from the database; reason why, you will notice a heavy loading.

2. Let's deploy on Vercel

Vercel is a platform for front-end frameworks and static sites, built to integrate with your headless content, commerce, or database.

It provides a friction-less developer experience to take care of the hard things: deploying instantly, scaling automatically, and serving personalized content around the globe.

- Step 1: Create a git repository, we created ours with GitHub and named it "next-food-app", and push your project code in there.

With Vercel, you don't need to run the Build and Start commands on your own. Just import your project repository and Vercel takes care of all during the deployment.

- Step 2: Use your GitHub Account to sign up with Vercel, HERE

Click on "Continue with GitHub" button:

Vercel sign up

After a successful sign up, you will be redirected here:

Iercel user dash

- Step 3: Click on the "New Project" button
When you click on "New Project", Vercel will directly link all your GitHub repositories to the page you are redirected to.

Image import

  • Import the repository you have just created, for us it will be the "next-food-app" repository,

Image debut depl

  • Click on Skip in the "Create a Team" section,
  • In the "Configure Project" section click on Deploy and wait for deployment.

During the deployment, Vercel runs $ npm run build and $ npm start in the project directory for the imported repository. And at every $ git push command, Vercel redeploys your project.

Image final depl

Congratulations! Now your the project is deployed, navigate to https://next-food-app.vercel.app/

Image navigate

3. Conclusion

Here we are at the end of this tutorial series. I hope that you like and use it and that you will go further with Next.js.

Feel free to reach out for questions on my Twitter.

Find the completed project HERE.

À bientôt.

Discussion (0)