Portfolio Case Study

How I Built My Food Recommendation Generator

This project is a web app that helps people find recipe ideas based on what they feel like eating. Instead of making the user guess an exact dish name, the app starts with simple preferences like cravings, diet, meal type, country, or dinner. From there, it searches for recipes, gathers the useful details, and presents them in a clean and easy-to-read format.

In plain language, I built a tool that turns a vague thought like “I want something spicy for dinner” into actual meal ideas with ingredients, steps, and links to the full recipe.

Python Flask JavaScript SerpApi BeautifulSoup HTML/CSS
Project Type
Recipe discovery web app
Main Goal
Help people go from cravings to real recipe ideas
What Happens Behind the Scenes
Search, collect, clean, rank, and display recipe results
Why It Matters
Makes food discovery easier and more personalized

Project Overview

People usually do not begin a food search by typing the exact name of a dish. Most of the time, they start with a feeling or preference. They may say, “I want something salty,” “I want food from Ghana,” or “I need a vegetarian breakfast.” That is the real-life behavior I designed this project around.

The goal of this app was to make that process easier. I wanted the user to be able to describe what they want in a natural way, and then let the application do the work of finding possible recipes, pulling out the important parts, and showing the best options first.

So rather than acting like a simple search bar, this project works more like a helper. It takes broad preferences, translates them into smarter searches, and then narrows down the results into something useful.

The simple idea: the user gives the app a few clues about what they want to eat, and the app turns those clues into better recipe suggestions.

What Problem Was I Trying to Solve?

What usually happens

On many recipe websites, the user needs to already know what they are looking for. That means the search works best if someone types a very specific dish name, such as “jollof rice” or “banana bread.”

But that is not always how people think. Many people know the kind of food they want, but not the exact name of the meal.

What I wanted to improve

I wanted to build an app that understands broader food intentions. A person should be able to say they want something spicy, a certain cuisine, a certain meal type, or a certain diet, and still get good results.

That is what makes the project more useful for everyday people. It starts from how people actually make food choices.

In non-technical terms: I was solving the gap between “I know what I feel like eating” and “I know the exact recipe name to search for.”

The User Side of the Experience

On the front of the app, the user sees a simple form with dropdown options. They can choose what they are craving, the cuisine or country they want to explore, their diet, and the type of meal.

  • Craving: sweet, salty, spicy, and so on
  • Cuisine or country: such as Nigerian, Indian, Mexican, Cameroonian, and more
  • Diet: vegan, vegetarian, gluten-free, and similar choices
  • Meal type: breakfast, lunch, dinner, snack, dessert, and more

After choosing those options, the user clicks a button and receives a list of recipe cards with images, ingredients, directions, and source links.

The Behind-the-Scenes Side

What the user sees is only the surface. In the background, the app is doing a lot more work. It takes the user's choices, builds a better search phrase, looks for recipe pages, reads the useful parts of those pages, compares them to the user’s preferences, and returns the strongest matches.

That is what makes this project more than just a pretty interface. It has a real decision-making process behind it.

Tech Stack Explained in Plain English

HTML, CSS, and JavaScript

These handle what the user sees and clicks. HTML gives the page structure, CSS gives it styling, and JavaScript makes it interactive so the form, buttons, and recipe results update without feeling static.

Simple way to think about it: this is the part that makes the app look good and respond to the user.

Python and Flask

Flask is the part that receives the user’s request and does the main processing work. It acts like the brain of the app. When someone clicks “Get Recommendation,” Flask is what receives the request, starts the search process, and sends the final recipe data back.

Simple way to think about it: Flask is the worker behind the curtain making the app actually function.

SerpApi and BeautifulSoup

SerpApi helps the app find recipe pages through search results. BeautifulSoup helps the app read the content on those pages. Once the app finds possible recipes, it needs a way to pull out the useful details like the title, image, ingredients, and cooking steps.

Simple way to think about it: one tool helps the app find recipes, and the other helps it read them.

A Simple Walkthrough of What Happens When Someone Uses the App

This is the easiest way to understand the project: follow one user action from start to finish.

The user chooses a craving, cuisine, diet, and meal type
The page sends those choices to the backend
The backend turns those choices into a smarter search
The app finds recipe pages online
The app reads the recipe details and cleans the data
The best matching recipes are shown back to the user
The important thing here is that the app is not just showing the first thing it finds. It is doing a series of steps to find results that better match what the person actually asked for.

How I Built It Step by Step

1

I started with the real user question

Before writing code, I thought about what a normal person would actually want from a food app. Most people do not open a recipe site saying, “I want dish X.” They often say, “I want something sweet,” or “I want dinner from a certain country.” That idea shaped the entire project.

Because of that, I decided the app should begin with broad, human-friendly options instead of forcing exact recipe names.

2

I designed the form people would interact with

I built a form with dropdown menus for craving, cuisine or country, diet, and meal type. I chose dropdowns because they make the experience simple and reduce typing mistakes.

This part matters because the quality of the output depends on the quality of the inputs. If the form is confusing, the whole experience feels harder. So I kept the input side clean and guided.

3

I added extra interface features to make it feel like a real product

I included a Get Recommendation button, a Surprise Me button, and a Stop button. The Surprise Me feature makes the app more fun and exploratory, while the Stop button gives the user more control.

I also added pagination so the results would not all pile up in one long overwhelming page. This helped the app feel more polished and easier to use.

4

I connected the page to the backend

Once the user picks their options, JavaScript gathers those choices and sends them to Flask. This is the handoff point between the part the user sees and the part that does the deeper work.

You can think of this like placing an order at a restaurant: the customer gives the order to the server, and then the kitchen takes over. In this project, JavaScript passes the request, and Flask acts like the kitchen.

5

I built smarter search phrases from the user’s choices

One of the most important parts of the project was not just taking the user's words literally. I created logic that combines the selected craving, cuisine, diet, and meal type into a more useful search phrase.

For example, if a user chooses India, the app may search using “Indian” because that wording is often more common on recipe websites. This improved the quality of the results.

Why this matters: a better search phrase usually leads to better recipe results.
6

I used SerpApi to gather possible recipe sources

After creating the search phrase, the app uses SerpApi to look up related pages. I treated these results as possible candidates, not as final answers.

That distinction is important. Just because a page appears in search results does not mean it is a perfect match. Some pages are list pages, some are low quality, and some do not fully match the user's request.

7

I read the recipe pages and pulled out the useful details

Once the app had possible links, I used BeautifulSoup and structured metadata parsing to read those pages and extract the most useful information. I focused on pieces like the recipe title, image, ingredient list, instructions, and source link.

This step is what transforms the project from “a list of links” into “actual recipe recommendations.” Instead of forcing the user to open many pages themselves, the app does some of that work first.

8

I cleaned and organized messy web data

Web pages are not all written the same way. One recipe site might structure ingredients neatly, while another may scatter them differently. That means the raw data can be messy.

I added cleaning and formatting logic so the information would look more consistent before it was shown to the user. This included organizing ingredients and instruction steps into a readable format.

Simple way to think about it: I took messy information from the internet and made it presentable.
9

I ranked the recipes instead of just showing random results

This is one of the most important parts of the project. I did not want the user to get whatever page happened to appear first. I wanted the app to decide which recipes were the strongest matches.

So I built ranking logic that checks how well each recipe matches the user's craving, cuisine, diet, and meal type. Recipes that match more of the user’s preferences are scored higher and shown first.

This is what makes the project feel more intelligent. It does not just find recipes. It tries to find the ones that make the most sense for the user.
10

I displayed the final results as recipe cards

After the app finishes searching, cleaning, and ranking, it sends the final recipe data back to the frontend. JavaScript then displays each recommendation as a recipe card.

Each card gives the user the essentials at a glance: the recipe title, image, cuisine label, ingredients, instructions, and a link to the full source. That way, the user can quickly compare options without feeling overwhelmed.

Frontend Features Explained Simply

  • Dropdown filters: these guide the user and make the app easy to use.
  • Surprise Me: this adds discovery and makes the app feel playful.
  • Stop button: this gives the user more control if they want to cancel a request.
  • Saved selections: the app remembers recent choices so the user does not have to keep reselecting them.
  • Pagination: this breaks large results into smaller pages so the screen stays cleaner.
  • Loading and empty states: the app clearly tells the user what is happening instead of leaving them confused.

Backend Features Explained Simply

  • Smarter search building: the app turns simple user choices into better web searches.
  • Recipe gathering: it looks for possible recipe pages instead of relying on one fixed database.
  • Recipe reading: it pulls out the details people care about most.
  • Data cleaning: it tidies messy information before showing it.
  • Relevance scoring: it decides which recipes are the best fit.
  • Clean response format: it sends back only the useful information the frontend needs.

Why the Ranking Logic Was So Important

If I had stopped at the search stage, this project would have felt like a basic wrapper around existing search results. That would not be very impressive or very useful. The real value comes from deciding which results deserve to be shown first.

For example, if someone asks for a spicy Nigerian dinner, not every recipe page that mentions Nigeria or spice should be treated the same. Some will be more relevant than others. My ranking logic helps sort those differences out.

In a non-technical sense, this is the part where the app starts to show judgment. It is trying to understand the user's intention, not just repeat whatever the internet throws back.

Challenges I Ran Into

  • Not all recipe websites are organized the same way.
  • Some search results lead to collections of recipes instead of one actual recipe page.
  • The internet is noisy, so some pages contain a lot of extra information that is not useful.
  • Country names and food labels are not always written the same way online.
  • Showing too many results at once can make the experience feel cluttered.

How I Solved Those Challenges

  • I supported more than one extraction method so the app could handle different website structures.
  • I separated the step of finding recipe pages from the step of reading recipe details.
  • I cleaned and standardized the data before sending it to the user interface.
  • I added country and cuisine matching logic to improve relevance.
  • I used pagination and clear UI feedback to keep the experience organized.

What I Learned from Building This

Real-world data is messy

Building with live web data taught me that information is rarely handed to you in a neat format. A big part of development is cleaning and organizing data so it becomes useful.

Good results matter as much as working code

The app could be technically functional but still not feel helpful if the recommendations are poor. This taught me that relevance and user satisfaction are part of the engineering work too.

User experience makes a big difference

Features like saved selections, a stop button, loading states, and pagination may seem small, but they make the app feel more polished and thoughtful.

How I Would Improve It Next

If I continue developing this project, I would want to make it even more personalized and scalable.

Mini Glossary for Non-Technical Readers

Frontend

This is the part of the app the user can actually see and interact with on the screen.

Backend

This is the behind-the-scenes part that processes requests, does the logic, and returns results.

API

An API is a way for one part of a system to talk to another. In this project, the page sends a request to the backend and receives recipe data back.

Scraping

Scraping means reading web pages and pulling out useful information from them, such as recipe titles, ingredients, or instructions.

Ranking Logic

This is the method the app uses to decide which results are the best match and should be shown first.

Final Reflection

This project helped me practice much more than just building a webpage. I had to think about the user’s real need, design a better search experience, work with outside data, clean messy information, and present the final results clearly.

What I like most about this project is that it shows how I approach problem-solving. I do not just want to make something look nice. I want to build tools that take a real everyday problem and make it simpler for the user.

In this case, the problem was food discovery. The solution was a recommendation app that starts with human preferences and turns them into useful meal ideas.