Create a Food Ordering App with Strapi and Next.js 1/7
Tags: strapi, stripe, nextjs
Published: 2023-06-29 15:24:41

**Tutorial updated by [Fredrick Emmanuel](https://strapi.io/user/fredrick-emmanuel) and [Paul Bratslavsky](https://strapi.io/user/paul-bratslavsky)** 

This tutorial will walk you through how to use [Next.js](https://strapi.io/integrations/nextjs-cms) to power your UI, complete using **GraphQL, Stripe, Strapi, and Next** to developing a full-stack application complete with the powerful Strapi (Headless CMS) powering the backend.

Get ready to develop an **online food ordering app, more info on the tech stack here:** [Next.js](https://strapi.io/integrations/nextjs-cms)**,** [GraphQL](https://graphql.org/)**,** [Stripe](http://stripe.com/) **and** [Strapi](https://strapi.io/)! From sign up to order, you are going to let users discover restaurants, dishes and order meals.

Your app will be complete with user login, registration, authentication, image upload, restaurant creation, dish creation, cart functionality, and stripe order integration.
The **demo of the final result** should make you hungry:

![Final Walk Through 3](https://d2zv2ciw0ln4h1.cloudfront.net/uploads/ezgif.com-optimize--11-.gif_9c7b390e92.gif)

> Note: The source code is available on GitHub for [*Frontend*](https://github.com/divofred/food-ordering-app) and [Backend](https://github.com/divofred/strapi-app).

Screenshots of final product:
![first](https://d2zv2ciw0ln4h1.cloudfront.net/uploads/Screen-Shot-2018-10-13-at-5.12.41-PM.png_26e07965ab.png)
![second](https://d2zv2ciw0ln4h1.cloudfront.net/uploads/Screen-Shot-2018-10-13-at-5.12.58-PM.png_3669089199.png)
![third](https://d2zv2ciw0ln4h1.cloudfront.net/uploads/Screen-Shot-2018-10-13-at-5.13.21-PM.png_e7e5d3e355.png)

### Strapi
[**Strapi**](https://strapi.io) [](https://github.com/strapi/strapi)is the most advanced open-source **Node.js Headless Content Management System** used to build scalable, secure, production-ready APIs quickly and efficiently saving developers countless hours of development.
With its extensible plugin system, it provides an enormous set of built-in features: Admin Panel, Authentication & Permissions management, Content Management, API Generator, etc. **Strapi is 100% open-source,** which means:

- Strapi is **completely free**.
- You can **host it on your servers**, so you own the data.
- It is entirely **customizable and extensible**, thanks to the plugin system.

### Next.js
[**Next**](https://nextjs.org/) [](https://strapi.io/integrations/nextjs-cms)is a lightweight **React** framework to create server-rendered applications. Next.js will take care of the heavy lifting of the application build such as *code splitting, HMR (hot module replacement) SSR (server-side rendering)* and allow us to focus on writing the code, not our build config.

### GraphQL
[**GraphQL**](https://github.com/graphql) is a query language also developed by Facebook to allow the front end of an application to easily query an application's API. Each query requests only the data needed to be rendered by the current view. This allows the developer to craft a great user experience across *multiple devices and screen sizes*.

### Stripe
[**Stripe**](https://github.com/stripe) is one payment processor for applications today. Stripe has developed the tools and SDKs to allow developers to craft and integrate *secure, compliant payment processing* into any app with ease.

## Table of contents

- 🏗️ [Setup](https://strapi.io/blog/nextjs-react-hooks-strapi-food-app-1) (part 1) - **Current**
- 🏠 [Restaurants](https://strapi.io/blog/nextjs-react-hooks-strapi-restaurants-2) (part 2)
- 🍔 [Dishes](https://strapi.io/blog/nextjs-react-hooks-strapi-dishes-3) (part 3)
- 🔐 [Authentication](https://strapi.io/blog/nextjs-react-hooks-strapi-auth-4) (part 4)
- 🛒 [Shopping Card](https://strapi.io/blog/nextjs-react-hooks-strapi-shopping-cart-5) (part 5)
- 💵 [Order and Checkout](https://strapi.io/blog/nextjs-react-hooks-strapi-checkout-6) (part 6)
- 🚀 [Bonus: Deploy](https://strapi.io/blog/nextjs-react-hooks-strapi-deploy) (part 7)

## 🏗️ Setup

### Next
To set up [Next.js](https://strapi.io/integrations/nextjs-cms) you will need an empty directory to install the dependencies and host our project root.
This project will be split into two parts, one for the front end (Next.js code) and one for the backend (Strapi code).

1. Run the code below in your terminal to create this project’s source folder.

```bash
    mkdir next-react-hooks-strapi-food-delivery
```

1. Next, Open the `next-react-hooks-strapi-food-delivery` folder in your favourite code editor, VS Code preferably and run the following code in the integrated terminal.

    The following code will create a folder named `frontend` and set up NextJS.

```bash
    mkdir Frontend
    cd Frontend
    npx create-next-app next-app
```

Setting up the NextJS application for the first time will require you to install the **create-next-app** package, as shown in the output below.

![Create-next-app install](https://paper-attachments.dropbox.com/s_6C0ECA10829B93D62998B06C40062587254EF184B701BBBA0364E3885E4704C3_1660656067111_image.png)


You should get a similar output to the one shown below.

![Next-app created successfully](https://paper-attachments.dropbox.com/s_6C0ECA10829B93D62998B06C40062587254EF184B701BBBA0364E3885E4704C3_1660663346574_image.png)


First things first, let's set up our environment variables to avoid hard coding the API URL and having to update it on every deployment. 
Create a new file in the project’s directory and add the following code.

```
    touch .env.development
```
`Path: /env.development`
```
    NEXT_PUBLIC_API_URL='http://localhost:1337'
```

**Adding Bootstrap**

This tutorial makes use of [react-strap](https://reactstrap.github.io/) to implement Bootstrap into the application.
React-strap is a front-end library to easily create Bootstrap components and styling. This will take care of the heavy lifting on the front end.
Open your terminal in the next-app directory and run the install `reactstrap` command below:

```bash
    npm install reactstrap
```

To import the CSS and share a Layout component across all pages, use the `_app.js` file inside the **pages directory**.

The `_app.js` file inside the pages directory will override the default App.js used by Next and be rendered on each page, allowing us to set and manage global styles and shared components in one place of the application.

> You can read more about the `_app.js` handling [here](https://nextjs.org/docs/advanced-features/custom-app)

1. Open the **pages** folder, select the `_app.js` and add the following code

Path: `/frontend/next-app/pages/_app.js`

```js
    /* _app.js */
    import React from "react";
    import App from "next/app";
    import Head from "next/head";
    
    export default class MyApp extends App {
      render() {
        const { Component, pageProps } = this.props;
        return (
          <>
            <Head>
              <link
                rel="stylesheet"
                href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
                integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm"
                crossOrigin="anonymous"
              />
            </Head>
    
            <Component {...pageProps} />
          </>
        );
      }
    }
```

2. Now add the following code inside the **index.js** file to insert **reactstrap** components.

Path: `/frontend/next-app/pages/index.js`

```js
    /* pages/index.js */
    import { Button, Alert } from "reactstrap";
    
    export default () => {  
      return (
        <div>
          <div>
            <Alert color="primary">
              Hello Project is strapi-next with Bootstrap
            </Alert>
            &nbsp; <Button color="primary">Hello from nextjs</Button>
          </div>
        </div>
      );
    };
```

3. Next, open your terminal in the next-app directory and start the next application by running the command below.

```bash
    npm run dev
```

Open this URL, [localhost:3000](http://localhost:3000), in your favourite browser to view the next app. You should get an output similar to the one below.

![Homepage](https://paper-attachments.dropbox.com/s_6C0ECA10829B93D62998B06C40062587254EF184B701BBBA0364E3885E4704C3_1660837536998_image.png)


**Designing the page**
Now that we have Bootstrap running inside of our Next project, we can style the shared frontend components like the nav bar.

1. Create a folder in the **next-app** directory named **components** to store all the components for the next application and create a file named **Layout.js.**

Next uses the `<Link>` component to perform the client-side routing between pages. The Link component is the next component and can accept any HTML element that has an onClick handler as a child component (`<a>`,`<button>`,`<div>` etc.).
To style our navbar, we can use the built-in CSS in JS syntax `<style jsx>` shipped by default with next.
Inserting CSS in JS as in next is as easy as:

```css
    <style jsx> {`
      a { color: yellow }
    `}
    </style>
```

This allows us to scope CSS to the components the style tag is in. You can also pass in the global option to set a global style across the project: `<style jsx global>` this would set styling across pages and components for all elements that match the CSS selector. You can read more on CSS in JS in the Next documents [here](https://nextjs.org/docs/basic-features/built-in-css-support#css-in-js).

2. Open the `Layout.js` file and create the shared layout components and insert the Stripe script (for later):

Path: `/frontend/next-app/components/Layout.js`

```js
    /* /components/Layout.js */
    
    import React from "react";
    import Head from "next/head";
    import Link from "next/link";
    
    import { Container, Nav, NavItem } from "reactstrap";
    
    export default function Layout(props) {
      const title = "Welcome to Nextjs";
      return (
        <div>
          <Head>
            <title>{title}</title>
            <meta charSet="utf-8" />
            <meta name="viewport" content="initial-scale=1.0, width=device-width" />
            <link
              rel="stylesheet"
              href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
              integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm"
              crossOrigin="anonymous"
            />
            <script src="https://js.stripe.com/v3" async/>
          </Head>
          <header>
            <style jsx>
              {`
                a {
                  color: white;
                }
              `}
            </style>
            <Nav className="navbar navbar-dark bg-dark">
              <NavItem>
                <Link href="/">
                  <a className="navbar-brand">Home</a>
                </Link>
              </NavItem>
    
              <NavItem className="ml-auto">
                <Link href="/login">
                  <a className="nav-link">Sign In</a>
                </Link>
              </NavItem>
    
              <NavItem>
                <Link href="/register">
                  <a className="nav-link"> Sign Up</a>
                </Link>
              </NavItem>
            </Nav>
          </header>
          <Container>{props.children}</Container>
        </div>
      );
    }
```
3. Edit the `_app.js` file to use the new Layout component across the application:

Path: `/frontend/next-app/pages/_app.js`

```js
    /* _app.js */
    import React from "react";
    import App from "next/app";
    import Head from "next/head";
    import Layout from "../components/Layout";
    export default class MyApp extends App {
      render() {
        const { Component, pageProps } = this.props;
        return (
          <>
            <Head>
              <link
                rel="stylesheet"
                href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
                integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm"
                crossOrigin="anonymous"
              />
            </Head>
            <Layout>
              <Component {...pageProps} />
            </Layout>
          </>
        );
      }
    }
```

You should now have a shared header bar across all your pages, as shown in the output below:

![Homepage with the nav bar](https://paper-attachments.dropbox.com/s_6C0ECA10829B93D62998B06C40062587254EF184B701BBBA0364E3885E4704C3_1660839707696_image.png)


**Creating the Login and Sign up page**

1. Create two additional pages in the **pages** folder to allow users to sign in and sign up named **login.js** and **register.js,** respectively.
2. Populate the files with the following code.

Path: `/frontend/next-app/pages/register.js`

```js
    /* pages/register.js */
    
    export default () => {
      return <h1>Sign Up</h1>;
    };
```
Path: `/frontend/next-app/pages/login.js`
```js
    /* pages/login.js */
    
    export default () => {
      return <h1>Sign In</h1>;
    };
```

You should now see the routes at [http://localhost:3000/login](http://localhost:3000/login) and [http://localhost:3000/register](http://localhost:3000/register)

### Setting up the database

This tutorial uses [PostgreSQL](https://www.postgresql.org/) as the database for this application.

1. Head on to the [download page](https://www.postgresql.org/download) for PostgreSQL and follow the prompts to install PostgreSQL on your local machine.

> This tutorial uses Windows 10 as its operating system.

2. Search and open up **PgAdmin** in the start menu of your computer. ***PgAdmin*** will help create and manage your ***Strapi database.***

> PgAdmin is installed when you install [PostgreSQL](https://www.postgresql.org/download/).

3. When PgAdmin opens, you will be prompted to put in the password entered during the installation as shown below.

![PyAdmin Screenshot](https://paper-attachments.dropbox.com/s_2AB6CD6238DB99E473ED13F1FBA90C2266A685066D162C9FB97895FCD9D8F400_1648245416520_PgAdmin+Password.jpg)

4. On the left navigation bar, click on Servers and click on PostgreSQL 14.

![A Sample Screenshot](https://paper-attachments.dropbox.com/s_2AB6CD6238DB99E473ED13F1FBA90C2266A685066D162C9FB97895FCD9D8F400_1648257844042_PgAdmin+clicks.jpg)

5. Right-click on Databases, hover over Create and click on Database.

![A Sample Screenshot](https://paper-attachments.dropbox.com/s_2AB6CD6238DB99E473ED13F1FBA90C2266A685066D162C9FB97895FCD9D8F400_1648259457129_PgAdmin+Rightclick.jpg)

6. You can name the database anything you desire, but, in this tutorial, the name of the database is nextapp. Once you're done naming the database, hit save.

![nextapp database](https://paper-attachments.dropbox.com/s_6C0ECA10829B93D62998B06C40062587254EF184B701BBBA0364E3885E4704C3_1660842285718_save+database.jpg)


The name of the database, nextapp, will be shown on the left navigation bar. Clicking on it will prompt a drop-down as shown below:

![nextapp](https://paper-attachments.dropbox.com/s_6C0ECA10829B93D62998B06C40062587254EF184B701BBBA0364E3885E4704C3_1660842130259_nexapp+showing.jpg)


### Install Strapi

Having a frontend is good, but your app needs a backend to manage users, restaurants, dishes and orders. To make the magic happen, let's create a Strapi API.

> Please use version >=[Node 9](https://nodejs.org/en/download) and have PostgreSQL installed and running on your machine.


**Create Strapi server**

1. Create a folder called `backend` in the project’s directory.
2. Open your terminal in the `backend`'s directory and run the following code to create a Strapi application.
```bash
    npx create-strapi-app strapiapp --quickstart
```

3. Running the above command for the first time will prompt you to install Strapi, as shown in the output below. Click y and hit enter to continue with the installation.

![create-strapi-app installation](https://paper-attachments.dropbox.com/s_6C0ECA10829B93D62998B06C40062587254EF184B701BBBA0364E3885E4704C3_1661111219373_image.png)

4. The quickstart option automatically builds the admin panel and runs Strapi in development mode. To start the Strapi in development mode, open your terminal in the strapiapp directory and run the command.

```bash
    npm run develop
```
5. Once the installation is complete, you should be redirected to http://localhost:1337/admin/auth/register-admin to create your first admin user.

![Admin sign up](https://paper-attachments.dropbox.com/s_6C0ECA10829B93D62998B06C40062587254EF184B701BBBA0364E3885E4704C3_1661125603160_Strapi+Admin+-+Google+Chrome+2022-08-21+23-18-24.gif)

6. As shown in the output below, Strapi wants to know a bit about you. You can choose to answer or decide to skip this question.

![Admin Sign Up_2](https://paper-attachments.dropbox.com/s_6C0ECA10829B93D62998B06C40062587254EF184B701BBBA0364E3885E4704C3_1661120392747_image.png)

7. Open the Backend folder, click on strapiapp, and select database.js from the config folder as shown below.

![database.js](https://paper-attachments.dropbox.com/s_6C0ECA10829B93D62998B06C40062587254EF184B701BBBA0364E3885E4704C3_1661481066701_image.png)

8. Replace the following code into the database.js file to configure the PostgreSQL database. 

```
      module.exports = ({ env }) => ({
          connection: {
            client: "postgres",
            connection: {
              host: env("DATABASE_HOST", "127.0.0.1"),
              port: env.int("DATABASE_PORT", 5432),
              database: env("DATABASE_NAME", "nextapp"),//Name of database
              user: env("DATABASE_USERNAME", "postgres"),//Default username
              password: env("DATABASE_PASSWORD", "12345678"),//Password to your PostgreSQL database
              ssl: env.bool("DATABASE_SSL", false),
            },
          },
        });
```

Good job, you successfully set up both Next.js and Strapi projects! 🎉

🏠 In the next section, you will learn how to display the **list of restaurants**: [https://strapi.io/blog/nextjs-react-hooks-strapi-restaurants-2](https://strapi.io/blog/nextjs-react-hooks-strapi-restaurants-2).