Updated April 2023 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 here
Screenshots of final product:
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.js
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-food-delivery
- Next, Open the
next-food-delivery
folder in your favourite code editor, VS Code preferably and run the following code in the integrated terminal.
npx create-next-app@latest frontend
You should see the following output.
➜ npx create-next-app@latest frontend
Need to install the following packages:
create-next-app@13.3.4
Ok to proceed? (y) y
Here are the options I selected for this tutorial, make sure you chose the same ones to follow along:
➜ next-food-delivery npx create-frontend frontend
Need to install the following packages:
create-next-app@13.3.4
Ok to proceed? (y) y
✔ Would you like to use TypeScript with this project? … No
✔ Would you like to use ESLint with this project? … Yes
✔ Would you like to use `src/` directory with this project? … No
✔ Would you like to use experimental `app/` directory with this project? … No
✔ What import alias would you like configured? … @/*
Creating a new Next.js app
The following code will create a folder named frontend
and set up NextJS.
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.
cd frontend
touch .env.development
Inside /.env.development
development file add the following code:
NEXT_PUBLIC_API_URL='http://localhost:1337'
Adding Tailwind
This tutorial makes use of Next And Tailwind to implement Tailwind into the application.
Tailwind is a front-end library to easily style your application. This will take care of the heavy lifting on the front end.
Open your terminal in the frontend
directory and run the following command:
Note: if you selected to use tailwind in the previous option you can omit this step.
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
Configure your template paths
Add the following code inside the tailwind.config.js
file.
1/** @type {import('tailwindcss').Config} */
2module.exports = {
3 content: [
4 "./app/**/*.{js,ts,jsx,tsx}",
5 "./pages/**/*.{js,ts,jsx,tsx}",
6 "./components/**/*.{js,ts,jsx,tsx}",
7 ],
8 theme: {
9 extend: {},
10 },
11 plugins: [],
12};
Add the Tailwind directives to your CSS
Add the @tailwind directives by replacing your css inside the styles/globals.css
file with the following.
1@tailwind base;
2@tailwind components;
3@tailwind utilities;
If the above was created for you automatically, you can remove all of the other css after the @tailwind directives.
We are importing our CSS in the _app.js
file inside the pages directory . This will allow us to share our CSS and and Layout component across all pages.
You can read more about the
_app.js
handling here
- Open the pages folder, select the
_app.js
to see where we are importing our CSS.
Path: /frontend/pages/_app.js
1import "@/styles/globals.css";
2
3export default function App({ Component, pageProps }) {
4 return <Component {...pageProps} />;
5}
- Now replace the code inside the index.js file with the following to test out tailwind CSS.
Path: frontend/pages/index.js
1import Head from "next/head";
2
3export default function Home() {
4 return (
5 <>
6 <Head>
7 <title>Create Next App</title>
8 <meta name="description" content="Generated by create next app" />
9 <meta name="viewport" content="width=device-width, initial-scale=1" />
10 <link rel="icon" href="/favicon.ico" />
11 </Head>
12 <main className="mx-auto container">
13 <button className="inline-block py-3 px-7 w-full md:w-auto text-lg leading-7 text-green-50 bg-green-500 hover:bg-green-600 font-medium text-center focus:ring-2 focus:ring-green-500 focus:ring-opacity-50 border border-transparent rounded-md shadow-sm">
14 Primary button
15 </button>
16 </main>
17 </>
18 );
19}
- Next, open your terminal in the frontend 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 Tailwind running inside of our Next project, we can style the shared frontend components like the nav bar.
- Create a folder in the frontend directory named components to store all the components for the next application and create a file named Layout.jsx.
Add the following code bellow:
Path: /frontend/components/Layout.js
1import Head from "next/head";
2import Link from "next/link";
3
4function Navigation() {
5 return (
6 <nav className="container mx-auto flex justify-between p-6 px-4">
7 <div className="flex justify-between items-center w-full">
8 <div className="xl:w-1/3">
9 <Link
10 className="block text-lg max-w-max ext-coolGray-500 hover:text-coolGray-900 font-medium"
11 href="/"
12 >
13 Food Order App
14 </Link>
15 </div>
16
17 <div className="xl:block xl:w-1/3">
18 <div className="flex items-center justify-end">
19 <Link
20 className="text-coolGray-500 hover:text-coolGray-900 font-medium"
21 href="/"
22 >
23 Home
24 </Link>
25 <Link
26 className="inline-block py-2 px-4 mr-2 leading-5 text-coolGray-500 hover:text-coolGray-900 bg-transparent font-medium rounded-md"
27 href="/login"
28 >
29 Log In
30 </Link>
31 <Link
32 className="inline-block py-2 px-4 text-sm leading-5 text-green-50 bg-green-500 hover:bg-green-600 font-medium focus:ring-2 focus:ring-green-500 focus:ring-opacity-50 rounded-md"
33 href="/register"
34 >
35 Sign Up
36 </Link>
37 </div>
38 </div>
39 </div>
40 </nav>
41 );
42}
43
44export default function Layout(props) {
45 const title = "Welcome to Nextjs";
46
47 return (
48 <div>
49 <Head>
50 <title>{title}</title>
51 <meta charSet="utf-8" />
52 <meta name="viewport" content="initial-scale=1.0, width=device-width" />
53 </Head>
54 <Navigation />
55 <div className="container mx-auto px-4">{props.children}</div>
56 </div>
57 );
58}
- Edit the
_app.js
file to use the new Layout component across the application:
Path: /frontend/frontend/pages/_app.js
1import "@/styles/globals.css";
2import Layout from "@/components/Layout";
3
4export default function App({ Component, pageProps }) {
5 return (
6 <Layout>
7 <Component {...pageProps} />
8 </Layout>
9 );
10}
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/pages/register.js
1/* pages/register.js */
2export default function RegisterRoute() {
3 return <h1>Sign Up</h1>;
4}
Path: /frontend/pages/login.js
1/* pages/login.js */
2
3export default function LoginRoute() {
4 return <h1>Log In</h1>;
5}
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
- Open your terminal in the
next-food-delivery
's directory and run the following code to create a Strapi application.
npx create-strapi-app@latest backend
- Running the above command for the first time will prompt you with steps to install Strapi Choose custom settings and follow the installation steps. Make sure to provide your credential for the postgres database that we created earlier.
Here are my options:
➜ next-food-delivery npx create-strapi-app@latest backend
? Choose your installation type Custom (manual settings)
? Choose your preferred language JavaScript
? Choose your default database client postgres
? Database name: nextapp
? Host: 127.0.0.1
? Port: 5432
? Username: postgres
? Password: ***********
? Enable SSL connection: No
Creating a project with custom database options.
- Once the installation is complete, you should see the following output.
Available commands in your project:
yarn develop
Start Strapi in watch mode. (Changes in Strapi project files will trigger a server restart)
yarn start
Start Strapi without watch mode.
yarn build
Build Strapi admin panel.
yarn strapi
Display all available commands.
You can start by doing:
You can start your project by running the following command:
cd backend
npm run develop
- Once the application starts you should see the following.
- 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 backend, and select database.js from the config folder to see your configuration file.
You should see the following code that was automatically setup for you when we created your Strapi project with your postgres credentials.
1//
2 postgres: {
3 connection: {
4 connectionString: env('DATABASE_URL'),
5 host: env('DATABASE_HOST', 'localhost'),
6 port: env.int('DATABASE_PORT', 5432),
7 database: env('DATABASE_NAME', 'strapi'),
8 user: env('DATABASE_USERNAME', 'strapi'),
9 password: env('DATABASE_PASSWORD', 'strapi'),
10 ssl: env.bool('DATABASE_SSL', false) && {
11 key: env('DATABASE_SSL_KEY', undefined),
12 cert: env('DATABASE_SSL_CERT', undefined),
13 ca: env('DATABASE_SSL_CA', undefined),
14 capath: env('DATABASE_SSL_CAPATH', undefined),
15 cipher: env('DATABASE_SSL_CIPHER', undefined),
16 rejectUnauthorized: env.bool(
17 'DATABASE_SSL_REJECT_UNAUTHORIZED',
18 true
19 ),
20 },
21 schema: env('DATABASE_SCHEMA', 'public'),
22 },
23 pool: { min: env.int('DATABASE_POOL_MIN', 2), max: env.int('DATABASE_POOL_MAX', 10) },
24 },
25//
You can find your database variables within your .env file.
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.
Ryan is an active member of the Strapi community and he's been contributing at a very early stage by writing awesome tutorial series to help fellow Strapier grow and learn.