Next.js Functions


Building a Recipe App with NEXT.js and Contentful

In the digital age, cooking has evolved from traditional recipe books to interactive recipe apps. Whether you’re a professional chef or a home cook, having a well-organized recipe app can make your culinary journey smoother and more enjoyable. In this tutorial, we’ll show you how to build your own Recipe App using NEXT.js and Contentful.

Building a Recipe App with NEXT.js and Contentful

1. Why NEXT.js and Contentful?

Before we dive into the development process, let’s briefly discuss why NEXT.js and Contentful make a fantastic combination for building a recipe app.

1.1. NEXT.js: The Perfect Framework

NEXT.js is a popular React framework for building fast, SEO-friendly web applications. It excels in server-side rendering, which means your recipes will load quickly and be easily discoverable by search engines. NEXT.js also provides a great developer experience with features like automatic code splitting, hot module replacement, and routing.

1.2. Contentful: A Headless CMS

Contentful is a powerful headless content management system (CMS) that allows you to create, manage, and deliver content to various platforms and devices. It’s perfect for storing and organizing your recipes, as it provides a user-friendly interface for content creators and a robust API for developers.

Now, let’s start building our Recipe App step by step.

2. Prerequisites

Before we begin, make sure you have the following prerequisites:

  • Node.js and npm (Node Package Manager) installed on your computer.
  • A Contentful account. You can sign up for free at
  • Basic knowledge of React and JavaScript.

Step 1: Setting Up Your NEXT.js Project

Let’s start by creating a new NEXT.js project. Open your terminal and run the following commands:

npx create-next-app recipe-app
cd recipe-app

This will scaffold a new NEXT.js project called “recipe-app.”

Step 2: Creating Components

Next, we’ll create the components needed for our Recipe App. Inside the “components” directory, create the following files:

  • Header.js
  • RecipeList.js
  • RecipeDetail.js
  • Footer.js

Here’s an example of the Header.js component:

// components/Header.js
import React from 'react';

const Header = () => {
  return (
      <h1>Recipe App</h1>

export default Header;

You can similarly create the other components and customize them according to your app’s design.

Step 3: Setting Up Routing

To navigate between different sections of our app, we’ll need to set up routing. NEXT.js provides an easy way to do this using the next/link package. First, install the package:

npm install next/link

Now, create a pages directory if it doesn’t already exist, and inside it, create the following files:

  • index.js
  • recipes.js
  • recipe/[id].js

Here’s an example of the pages/index.js file:

// pages/index.js
import Link from 'next/link';
import Header from '../components/Header';

const Home = () => {
  return (
      <Header />
      <h2>Welcome to Recipe App</h2>
      <Link href="/recipes">
        <a>View Recipes</a>

export default Home;

In the above code, we import the Link component from NEXT.js to create navigation links.

Step 4: Creating the Recipe Data Model

To store and manage our recipes, we’ll define a data model using Contentful. Log in to your Contentful account and create a new content model called “Recipe.” Add the following fields:

  • Title (Short Text)
  • Description (Long Text)
  • Ingredients (Long Text)
  • Instructions (Long Text)
  • Image (Media)

Once you’ve defined your content model, create some sample recipes using the Contentful web interface.

Step 5: Integrating Contentful

Now that we have our data model in place, it’s time to integrate Contentful into our NEXT.js app. We’ll use the contentful package to fetch data from Contentful.

Install the contentful package:

npm install contentful

Create a configuration file to store your Contentful credentials. You can do this by adding a .env.local file to the root of your project with the following content:


Replace your_space_id and your_access_token with your actual Contentful space ID and access token.

Next, create a utility function to fetch recipes from Contentful. In the utils directory, create a file called contentful.js:

// utils/contentful.js
import { createClient } from 'contentful';

const client = createClient({
  space: process.env.CONTENTFUL_SPACE_ID,
  accessToken: process.env.CONTENTFUL_ACCESS_TOKEN,

export async function getRecipes() {
  const entries = await client.getEntries({ content_type: 'recipe' });
  return entries.items;

In this code, we’re using the Contentful SDK to create a client and fetch recipes based on the content type “recipe.”

Step 6: Fetching and Displaying Recipes

With the Contentful integration in place, we can now fetch and display recipes in our app. Let’s modify the pages/recipes.js file:

// pages/recipes.js
import React, { useEffect, useState } from 'react';
import Header from '../components/Header';
import { getRecipes } from '../utils/contentful';

const Recipes = () => {
  const [recipes, setRecipes] = useState([]);

  useEffect(() => {
    async function fetchRecipes() {
      const data = await getRecipes();

  }, []);

  return (
      <Header />
        { => (
          <li key={}>{recipe.fields.title}</li>

export default Recipes;

In this code, we use the useState and useEffect hooks to fetch recipes from Contentful when the component mounts and display them as a list.

Step 7: Creating Recipe Detail Pages

To display individual recipe details, we’ll create dynamic pages for each recipe. Modify the pages/recipe/[id].js file as follows:

// pages/recipe/[id].js
import React, { useEffect, useState } from 'react';
import { useRouter } from 'next/router';
import Header from '../../components/Header';
import { getRecipe } from '../../utils/contentful';

const RecipeDetail = () => {
  const router = useRouter();
  const { id } = router.query;
  const [recipe, setRecipe] = useState(null);

  useEffect(() => {
    async function fetchRecipe() {
      const data = await getRecipe(id);

    if (id) {
  }, [id]);

  if (!recipe) {
    return <div>Loading...</div>;

  return (
      <Header />

export default RecipeDetail;

In this code, we use the useRouter hook from NEXT.js to access the route parameter id and fetch the corresponding recipe from Contentful.

Step 8: Styling Your Recipe App

Styling is an essential part of any web application. You can style your Recipe App using CSS, or if you prefer a more structured approach, you can use a CSS-in-JS solution like styled-components or a CSS framework like Tailwind CSS.

For example, to use styled-components, you can install it with:

npm install styled-components

Then, create styled components for your app, such as RecipeCard, RecipeDetailContainer, and so on. Be creative and make your app visually appealing.

Step 9: Deployment

Once you’ve built and styled your Recipe App, it’s time to deploy it to a hosting provider. NEXT.js provides various deployment options, including Vercel, Netlify, and more. Choose the one that suits your needs and follow their deployment instructions.


In this tutorial, we’ve shown you how to create a Recipe App using NEXT.js and Contentful. We covered setting up your NEXT.js project, creating components, setting up routing, integrating Contentful as a headless CMS, fetching and displaying recipes, creating dynamic recipe detail pages, styling your app, and deploying it to the web. With this knowledge, you can expand your app by adding features like user authentication, searching, and user-generated content. Enjoy building your Recipe App, and happy cooking!

Building a Recipe App with NEXT.js and Contentful opens up a world of possibilities for food enthusiasts, chefs, and anyone who loves cooking. By following the steps outlined in this tutorial, you can create a powerful and visually appealing platform to share and discover delicious recipes.

Previously at
Flag Argentina
time icon
Accomplished Senior Software Engineer with Next.js expertise. 8 years of total experience. Proficient in React, Python, Node.js, MySQL, React Hooks, and more.