Recipe Guide | Recipe Discovery & Management Platform - Next.js, PostgreSQL, Redis, Spoonacular API, Contentful CMS FullStack Project
A modern full-stack recipe app to search, save, and manage recipes—with favourites, collections, meal planning, AI-powered analysis, and more. Built for learning and production use.
- Live-Demo: https://recipe-smart.vercel.app/
- Overview
- Features
- Technology Stack
- Project Structure
- Getting Started
- Environment Variables
- How to Run
- Project Walkthrough
- API Endpoints
- Components & Reusability
- Routes
- Database Schema
- Keywords
- Conclusion
Recipe Guide is a modern full-stack recipe discovery and management platform built with Next.js 15, React 18, TypeScript, and PostgreSQL. It integrates the Spoonacular API for recipe data and provides features like recipe search, favourites, collections, meal planning, shopping lists, AI-powered recipe analysis, blog (Contentful CMS), and business insights.
The app follows a server/client component separation architecture, uses NextAuth v5 for authentication (Google OAuth + email/password), and is deployment-ready for Vercel with optional Redis (Upstash) caching and Sentry error tracking.
| Feature | Description |
|---|---|
| Recipe Search | Advanced search with filters (cuisine, diet, type, ingredients) |
| Recipe Details | Full recipe info, nutrition, taste data, instructions, wine pairing |
| Favourites | Save and manage favourite recipes (auth required) |
| Collections | Create custom recipe collections with custom ordering |
| Meal Planning | Weekly meal planner with breakfast, lunch, dinner, snack slots |
| Shopping List | Auto-generated shopping lists from recipes |
| AI Features | Recipe analysis, recommendations, modifications, weather-based suggestions |
| Blog | Contentful CMS–powered blog posts |
| Business Insights | Platform statistics, AI predictions, trends |
| API Status | Real-time API endpoint health monitoring |
| API Docs | Endpoint documentation grouped by category |
| Layer | Technology |
|---|---|
| Framework | Next.js 15 (App Router) |
| UI | React 18, Tailwind CSS, ShadCN UI (Radix), Framer Motion |
| Language | TypeScript 5.7 |
| Database | PostgreSQL (NeonDB), Prisma ORM |
| Auth | NextAuth v5 (JWT, Google OAuth, Credentials) |
| Caching | Upstash Redis (optional) |
| Recipe Data | Spoonacular API |
| CMS | Contentful |
| Image Upload | Cloudinary |
| Monitoring | Sentry, PostHog |
| Hosting | Vercel |
recipe-spoonacular/
├── app/ # Next.js App Router
│ ├── api/ # API routes
│ │ ├── [...path]/ # Unified API handler (recipes, collections, etc.)
│ │ ├── auth/ # NextAuth, login, signup
│ │ ├── jobs/ # Scheduled jobs (QStash)
│ │ └── test/ # Test endpoints (Redis)
│ ├── api-docs/ # API documentation page
│ ├── api-status/ # API status monitoring page
│ ├── blog/ # Blog (list + [slug])
│ ├── business-insights/ # Platform analytics
│ ├── recipe/[id]/ # Recipe detail page
│ ├── layout.tsx # Root layout + metadata
│ └── page.tsx # Home page
├── src/
│ ├── components/ # React components
│ │ ├── analysis/ # AI recipe analysis
│ │ ├── auth/ # Login, Register dialogs
│ │ ├── blog/ # Blog card, list, detail
│ │ ├── collections/ # Collection manager, cards
│ │ ├── common/ # ErrorBoundary, EmptyState, etc.
│ │ ├── filters/ # Advanced filters, presets
│ │ ├── hero/ # Hero search section
│ │ ├── insights/ # Business insights dashboard
│ │ ├── layout/ # Navbar, Footer, TabNavigation
│ │ ├── meal-planning/ # Meal planner
│ │ ├── pages/ # Page-level client components
│ │ ├── recipes/ # RecipeCard, RecipeDetailCard, etc.
│ │ ├── search/ # SearchInput, metadata
│ │ ├── shopping/ # Shopping list generator
│ │ ├── skeletons/ # Loading skeletons
│ │ ├── status/ # API status dashboard
│ │ ├── ui/ # ShadCN UI primitives
│ │ ├── videos/ # Recipe video player
│ │ └── weather/ # Weather-based suggestions
│ ├── config/ # Upload presets, config
│ ├── context/ # AuthContext, RecipeContext
│ ├── hooks/ # useRecipes, useCollections, etc.
│ ├── lib/ # posthog, utils
│ ├── utils/ # Helpers, mock data, generators
│ └── types.ts # Shared TypeScript types
├── lib/ # Server-side utilities
│ ├── api-key-tracker.ts # Spoonacular API key rotation
│ ├── api-utils-nextjs.ts # CORS, auth helpers
│ ├── prisma.ts # Prisma client
│ ├── recipe-api.ts # Spoonacular API calls
│ ├── redis-cache.ts # Redis caching
│ └── redis.ts # Upstash Redis client
├── prisma/
│ └── schema.prisma # Database schema
├── public/ # Static assets
├── auth.ts # NextAuth configuration
└── instrumentation.ts # Sentry instrumentation- Node.js 18+
- npm or pnpm
- PostgreSQL (e.g. NeonDB)
- Spoonacular API key (free tier: spoonacular.com/food-api)
# Clone the repository
git clone https://github.com/arnobt78/recipe-spoonacular.git
cd recipe-spoonacular
# Install dependencies
npm install
# Copy environment file and fill in values
cp .env.example .env.local
# Generate Prisma client
npm run prisma:generate
# Push schema to database (creates tables)
npm run prisma:push
# Start development server
npm run devOpen http://localhost:3000.
Create a .env.local file in the project root. Use .env.example as a template.
# Spoonacular API (required for recipe data)
API_KEY=your_spoonacular_api_key_here
# Optional: additional keys for rotation (API_KEY_2, API_KEY_3, etc.)
# Database (PostgreSQL)
DATABASE_URL=postgresql://user:password@host/database?sslmode=require# NextAuth v5
AUTH_SECRET=your-secret-here # Generate: openssl rand -base64 32
AUTH_URL=http://localhost:3000 # Production: https://your-domain.com
# Google OAuth (optional)
GOOGLE_ID=your-google-client-id
GOOGLE_SECRET=your-google-client-secret
# Or: GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET# Redis (Upstash) - for caching
UPSTASH_REDIS_URL=https://xxx.upstash.io
UPSTASH_REDIS_TOKEN=your-token
# Contentful CMS - for blog
CMS_SPACE_ID=your-space-id
CMS_DELIVERY_TOKEN=your-delivery-token
CMS_ENVIRONMENT=master
# Cloudinary - for image uploads
CLOUDINARY_CLOUD_NAME=your-cloud-name
CLOUDINARY_API_KEY=your-api-key
CLOUDINARY_API_SECRET=your-api-secret
# AI / LLM (OpenRouter, Gemini, etc.)
OPENROUTER_API_KEY=your-key
GOOGLE_GEMINI_API_KEY=your-key
GROQ_LLAMA_API_KEY=your-key
HUGGING_FACE_INFERENCE_API_KEY=your-key
# Weather (OpenWeather) - for weather-based suggestions
OPENWEATHER_API_KEY=your-key
# Email (Resend or Brevo) - for recipe sharing
RESEND_TOKEN=your-token
BREVO_API_KEY=your-key
EMAIL_SENDER_ADDRESS=noreply@yourdomain.com
# Sentry - error tracking
SENTRY_DSN=your-sentry-dsn
# PostHog - analytics
NEXT_PUBLIC_POSTHOG_KEY=your-key
NEXT_PUBLIC_POSTHOG_HOST=https://app.posthog.com
# App URL (for metadata, links)
NEXT_PUBLIC_APP_URL=http://localhost:3000
NEXT_PUBLIC_API_URL=http://localhost:3000| Variable | How to Get |
|---|---|
API_KEY |
Spoonacular → Sign up, copy API key |
DATABASE_URL |
NeonDB → Create project, copy connection string |
AUTH_SECRET |
Run openssl rand -base64 32 |
GOOGLE_ID / GOOGLE_SECRET |
Google Cloud Console → Credentials → OAuth 2.0 Client ID |
UPSTASH_REDIS_* |
Upstash → Create Redis database |
CMS_* |
Contentful → Space Settings → API keys |
CLOUDINARY_* |
Cloudinary → Dashboard |
SENTRY_DSN |
Sentry → Create project, copy DSN |
| Command | Description |
|---|---|
npm run dev |
Start dev server (Turbo) at http://localhost:3000 |
npm run dev:webpack |
Start dev server (Webpack) |
npm run build |
Production build |
npm run start |
Start production server |
npm run lint |
Run ESLint |
npm run prisma:generate |
Generate Prisma client |
npm run prisma:push |
Push schema to database |
npm run prisma:studio |
Open Prisma Studio |
- Hero search with a search bar and advanced filters.
- Tabs: Home, Favourites, Collections, Meal Plan, Shopping List.
- Search results from Spoonacular API with dietary badges, scores, and images.
- Full recipe info: instructions, ingredients, nutrition, taste, wine pairing.
- Tabs: Details, Summary, Info, Nutrition, Taste.
- Actions: Add to favourites, collections, meal plan, shopping list.
- User notes, images, videos (when logged in).
- List of blog posts from Contentful CMS.
- Individual post at
/blog/[slug].
- User stats, recipe activity, AI predictions, trends.
- Popular recipes, top contributors, recent activity.
- Real-time status of main API endpoints.
- Auto-refresh every 10 seconds.
- Endpoint reference grouped by category.
- Method badges, paths, and params.
The app uses a unified API handler at /api/[...path], which routes to different logic by path.
| Method | Path | Description |
|---|---|---|
| GET | /api/recipes/search |
Search recipes (searchTerm, page, filters) |
| GET | /api/recipes/autocomplete |
Autocomplete suggestions |
| GET | /api/recipes/[id]/information |
Full recipe details |
| GET | /api/recipes/[id]/summary |
Recipe summary |
| GET | /api/recipes/[id]/similar |
Similar recipes |
| GET | /api/recipes/favourite |
User favourites (auth) |
| POST | /api/recipes/favourite |
Add favourite (auth) |
| DELETE | /api/recipes/favourite |
Remove favourite (auth) |
| Method | Path | Description |
|---|---|---|
| GET | /api/food/wine/dishes |
Dishes for a wine |
| GET | /api/food/wine/pairing |
Wine pairing for a food |
| Method | Path | Description |
|---|---|---|
| GET | /api/collections |
List collections (auth) |
| GET | /api/collections/[id] |
Get collection (auth) |
| GET | /api/collections/[id]/items |
Collection items (auth) |
| POST | /api/collections |
Create collection (auth) |
| POST | /api/collections/[id]/items |
Add item (auth) |
| PUT | /api/collections/[id] |
Update collection (auth) |
| DELETE | /api/collections/[id] |
Delete collection (auth) |
| DELETE | /api/collections/[id]/items |
Remove item (auth) |
| Method | Path | Description |
|---|---|---|
| GET | /api/meal-plan |
Get meal plan (auth) |
| POST | /api/meal-plan |
Add to meal plan (auth) |
| DELETE | /api/meal-plan |
Clear meal plan (auth) |
| GET | /api/shopping-list |
Get shopping list (auth) |
| POST | /api/shopping-list |
Create/update list (auth) |
| PUT | /api/shopping-list |
Update list (auth) |
| DELETE | /api/shopping-list |
Clear list (auth) |
| Method | Path | Description |
|---|---|---|
| GET | /api/cms/blog |
List blog posts |
| GET | /api/cms/blog/[slug] |
Single blog post |
| GET | /api/business-insights |
Platform statistics |
| GET | /api/status |
API health status |
Most components are self-contained and can be reused by copying the component and its dependencies.
Example: Recipe card
// src/components/recipes/RecipeCard.tsx
import RecipeCard from "@/components/recipes/RecipeCard";
<RecipeCard recipe={recipe} onFavouriteToggle={() => {}} isFavourite={false} />;Example: Search input
import SearchInput from "@/components/search/SearchInput";
<SearchInput
onSearch={(term) => console.log(term)}
placeholder="Search recipes..."
/>;- Pages (
src/components/pages/) – full-page client components. - Features (
src/components/recipes/,collections/, etc.) – feature-specific components. - UI (
src/components/ui/) – ShadCN primitives (Button, Card, Dialog, etc.). - Skeletons (
src/components/skeletons/) – loading placeholders.
import { useRecipes } from "@/hooks/useRecipes";
import { useCollections } from "@/hooks/useCollections";
import { useIsFavourite } from "@/hooks/useIsFavourite";
const { data, isLoading, searchRecipes } = useRecipes();
const { collections, createCollection } = useCollections();
const { isFavourite, toggleFavourite } = useIsFavourite(recipeId);| Route | Type | Description |
|---|---|---|
/ |
Static | Home (search, tabs) |
/recipe/[id] |
Dynamic | Recipe detail |
/blog |
Static | Blog list |
/blog/[slug] |
Dynamic | Blog post |
/business-insights |
Static | Analytics dashboard |
/api-status |
Static | API status page |
/api-docs |
Static | API docs page |
/test-sentry |
Static | Sentry test page |
Key models (Prisma):
- User – Auth, profile, relations
- FavouriteRecipes – User favourites
- RecipeCollection – Custom collections
- CollectionItem – Items in collections
- RecipeNote – User notes on recipes
- MealPlan / MealPlanItem – Meal planning
- ShoppingList – Shopping lists
- RecipeImage – User-uploaded images (Cloudinary)
- FilterPreset – Saved search filters
- RecipeVideo – User-added videos
recipe app, Next.js, React, TypeScript, Spoonacular API, PostgreSQL, Prisma, NextAuth, full-stack, meal planning, shopping list, recipe collections, favourites, AI recipe, Contentful, Cloudinary, Tailwind CSS, ShadCN, Vercel, Redis, Sentry
Recipe Guide is a full-featured recipe platform built with modern web technologies. It demonstrates:
- Next.js 15 App Router with server and client components
- Prisma + PostgreSQL for data
- NextAuth for OAuth and credentials
- REST API design with a unified handler
- ShadCN UI and Tailwind for consistent design
- API key rotation, caching, and error monitoring
Use it as a reference for building similar apps or as a base to extend with new features.
This is an open-source project - feel free to use, enhance, and extend this project further!
If you have any questions or want to share your work, reach out via GitHub or my portfolio at https://www.arnobmahmud.com/.
Enjoy building and learning! 🚀
Thank you! 😊