Tutorial updated by Fredrick Emmanuel and Paul Bratslavsky
This tutorial will walk you through how to use Next.js 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, GraphQL, Stripe and Strapi! 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:
Note: The source code is available on GitHub for Frontend and Backend.
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 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 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 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 (part 1) - Current
- 🏠 Restaurants (part 2)
- 🍔 Dishes (part 3)
- 🔐 Authentication (part 4)
- 🛒 Shopping Card (part 5)
- 💵 Order and Checkout (part 6)
- 🚀 Bonus: Deploy (part 7)
🏗️ Setup
Next
To set up Next.js 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).
- Run the code below in your terminal to create this project’s source folder.
mkdir next-react-hooks-strapi-food-delivery
-
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.
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.
You should get a similar output to the one shown below.
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 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:
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
- Open the pages folder, select the
_app.js
and add the following code
Path: /frontend/next-app/pages/_app.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} />
</>
);
}
}
- Now add the following code inside the index.js file to insert reactstrap components.
Path: /frontend/next-app/pages/index.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>
<Button color="primary">Hello from nextjs</Button>
</div>
</div>
);
};
- Next, open your terminal in the next-app directory and start the next application by running the command below.
npm run dev
Open this URL, localhost:3000, in your favourite browser to view the next app. You should get an output similar to the one below.
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.
- 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:
<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.
- 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
/* /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>
);
}
- Edit the
_app.js
file to use the new Layout component across the application:
Path: /frontend/next-app/pages/_app.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:
Creating the Login and Sign up page
- Create two additional pages in the pages folder to allow users to sign in and sign up named login.js and register.js, respectively.
- Populate the files with the following code.
Path: /frontend/next-app/pages/register.js
/* pages/register.js */
export default () => {
return <h1>Sign Up</h1>;
};
Path: /frontend/next-app/pages/login.js
/* pages/login.js */
export default () => {
return <h1>Sign In</h1>;
};
You should now see the routes at http://localhost:3000/login and http://localhost:3000/register
Setting up the database
This tutorial uses PostgreSQL as the database for this application.
- Head on to the download page for PostgreSQL and follow the prompts to install PostgreSQL on your local machine.
This tutorial uses Windows 10 as its operating system.
- 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.
- When PgAdmin opens, you will be prompted to put in the password entered during the installation as shown below.
- On the left navigation bar, click on Servers and click on PostgreSQL 14.
- Right-click on Databases, hover over Create and click on Database.
- 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.
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:
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 and have PostgreSQL installed and running on your machine.
Create Strapi server
- Create a folder called
backend
in the project’s directory. - Open your terminal in the
backend
's directory and run the following code to create a Strapi application.
npx create-strapi-app strapiapp --quickstart
- 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.
- 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.
npm run develop
- Once the installation is complete, you should be redirected to http://localhost:1337/admin/auth/register-admin to create your first admin user.
- 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.
- Open the Backend folder, click on strapiapp, and select database.js from the config folder as shown below.
- 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.