Last Updated : 23 Jul, 2025
In this tutorial, we'll create a Recipe Generator App using Next.js, a React framework that allows users to generate random recipes. This type of application can be useful for people looking for new meal ideas or wanting to explore different cuisines. application fetches recipe data from API and displays it to the user.
Output Preview: Let us have a look at how the final output will look like.
Prerequisites: Approach to Create Recipe Generator:Step 1: Create a application of NextJS using the following command.
npx create-next-app recipe-generator
Step 2: Navigate to project directory
cd recipe-generator
Step 3: Install the necessary package in your project using the following command.
npm install bootstrap
npm install axios
Step 4: Create the folder structure as shown below and create the files in respective folders.
Project Structure:The updated dependencies in package.json file will look like:
"dependencies": {
"axios": "^1.6.7",
"bootstrap": "^5.3.3",
"next": "14.1.0",
"react": "^18",
"react-dom": "^18"
}
Example: Below are the components which describes the implementation of the Recipe Generator.
JavaScript
// page.js
import RecipeGenerator from '@/components/RecipeGenerator';
import React from 'react';
const page = () => {
return (
<div>
<RecipeGenerator />
</div>
)
}
export default page
JavaScript
// Navbar.js
import React from 'react';
import 'bootstrap/dist/css/bootstrap.min.css';
const Navbar = () => {
return (
<nav className="nav justify-content-center navbar-light bg-success">
<li className="nav-item">
<a className="nav-link text-light" href="#"><h2>GFG Recipe generator</h2></a>
</li>
</nav>
);
};
export default Navbar;
JavaScript
// RecipeGenerator.js
'use client'
import { useState, useEffect } from 'react';
import axios from 'axios';
import 'bootstrap/dist/css/bootstrap.min.css';
import Navbar from './Navbar';
import RecipeCard from '@/components/RecipeCard';
const RecipeGenerator = () => {
const [recipes, setRecipes] = useState([]);
const [search, setSearch] = useState('');
const [selectedRecipe, setSelectedRecipe] = useState(null);
const APP_ID = 'YOUR_EDAMAM_APP_ID';
const APP_KEY = 'YOUR_EDAMAM_APP_KEY';
const generateRecipe = async () => {
try {
const response = await axios.get(`https://api.edamam.com/search?q=$%7Bsearch%7D&app_id=bbb0cce2&app_key=2fe683efd1286808ab9fc1d52132e3dd%60);
if (response.data.hits.length > 0) {
setRecipes(response.data.hits);
}
} catch (error) {
console.error('Failed to fetch recipe', error);
}
};
const openModal = (recipe) => {
setSelectedRecipe(recipe);
document.getElementById('exampleModal').style.display = 'block';
};
const closeModal = () => {
setSelectedRecipe(null);
document.getElementById('exampleModal').style.display = 'none';
};
return (
<>
<Navbar />
<div className="container mt-3 justify-content-center">
<div className="row">
<div className="col mb-4">
<input type="text" value={search} onChange={(e) => setSearch(e.target.value)} className="form-control" />
</div>
<div className="col">
<button onClick={generateRecipe} className="btn btn-success justify-content-center">Generate Recipe</button>
</div>
</div>
{recipes.length === 0 ? (
<p>No recipes found</p>
) : (
<RecipeCard recipes={recipes}
openModal={openModal}
closeModal={closeModal}
selectedRecipe={selectedRecipe}
/>
)}
</div>
</>
);
};
export default RecipeGenerator;
JavaScript
// RecipeCard.js
import React from 'react'
import 'bootstrap/dist/css/bootstrap.min.css';
const RecipeCard = ({recipes, openModal, closeModal, selectedRecipe}) => {
return (
<div className="row">
{
recipes.map((recipe) => (
<div key={recipe.recipe.label} className="col-md-3 mb-3">
<div className="card">
<img src={recipe.recipe.image} className="card-img-top" style={{ height: '200px', objectFit: 'cover' }} alt={recipe.recipe.label} />
<div className="card-body">
<h5 className="card-title">{recipe.recipe.label}</h5>
<p className="card-text">Calories: {recipe.recipe.calories.toFixed(2)}</p>
<button onClick={() => openModal(recipe)} className="btn btn-outline-success">View Ingredients</button>
</div>
</div>
</div>
))
}
<div className="modal" id="exampleModal" tabIndex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true" onClick={closeModal}>
<div className="modal-dialog modal-dialog-centered" role="document" style={{ margin: "auto" }}>
<div className="modal-content" onClick={(e) => e.stopPropagation()}>
<div className="modal-header">
<h5 className="modal-title" id="exampleModalLabel">Ingredients{' '}</h5>
<button type="button" className="close" data-dismiss="modal" aria-label="Close" onClick={closeModal}>
<span aria-hidden="true">×</span>
</button>
</div>
<div className="modal-body">
<ul>
{selectedRecipe && selectedRecipe.recipe.ingredientLines.map((ingredient, index) => (
<li key={index}>{ingredient}</li>
))}
</ul>
</div>
</div>
</div>
</div>
</div>
)
}
export default RecipeCard
Start your application using the following command.
npm run dev
Output: Open web-browser and type the following URL http://localhost:3000/
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4