BiteCraft — Premium Culinary Directory & Recipe Sharing Platform

BiteCraft — Premium Culinary Directory & Recipe Sharing Platform

Next.js 15 (App Router)React 19TypeScriptSupabase (Postgres)Row-Level SecurityDynamic ScalerSchema.org JSON-LDTailwind CSSVercel Edge Network

BiteCraft is a restaurant-grade recipe sharing platform and culinary creator directory engineered for passionate home cooks, food bloggers, and professional culinary artists to discover, dynamically scale, and publish chef-crafted recipes with confidence. Built with Next.js 15 App Router, React 19, TypeScript, and Supabase (PostgreSQL with Row-Level Security), the platform features a Dribbble-style visual culinary masonry grid, interactive serving ratio scaling (proportional ingredient recalculation), structured schema.org/Recipe JSON-LD generation for Google Rich Snippets, and an auth-guarded chef submission studio.

🍽️Overview & Restaurant-Grade Culinary Architecture

Most online recipe websites are overloaded with bloated lifestyle ads, laggy popups, and unformatted ingredient walls that frustrate cooks mid-preparation. I designed and engineered BiteCraft to reverse this paradigm: a clean, high-performance culinary discovery hub built for speed, utility, and aesthetic delight. Home cooks can discover restaurant-grade dishes through a visual card directory, dynamically scale ingredient yields from 2 to 12 servings with zero rounding errors, and bookmark favorites to their private kitchen club.

🍳Relational Recipe Modeling & Anti-Spam Chef Submission

To guarantee data integrity and protect the platform from low-quality automated recipe scrapers:

  • Structured Relational Schema: Recipes, normalized ingredient quantities, step-by-step instruction steps, and chef profiles are linked via foreign keys in Supabase PostgreSQL.
  • Auth-Guarded Chef Studio: Recipe creation requires verified authentication (or one-click demo login), ensuring every published dish is attributable to an authentic creator.
  • Row-Level Security (RLS): Strict database policies allow public read access for published dishes while isolating private drafts, custom collections, and saved bookmarks.
  • Zero Ad Bloat: Recipes render with distraction-free typography, step timers, and instant printable chef cards.

🗄️PostgreSQL Relational Schema with Row-Level Security

PostgreSQL table definitions enforce referential integrity and strict creator tenancy:

-- supabase/migrations/20261021_recipes_schema.sql - BiteCraft Core Schema
CREATE TABLE public.recipes (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  chef_id UUID REFERENCES auth.users(id) ON DELETE CASCADE NOT NULL,
  title TEXT NOT NULL,
  slug TEXT UNIQUE NOT NULL,
  description TEXT NOT NULL,
  category TEXT NOT NULL CHECK (category IN ('Italian', 'Artisan Bake', 'Quick 15-Min', 'Plant-Based', 'Seafood', 'Dessert')),
  cuisine TEXT,
  prep_time_minutes INT NOT NULL,
  cook_time_minutes INT NOT NULL,
  default_servings INT NOT NULL DEFAULT 4,
  calories_per_serving INT,
  cover_image_url TEXT NOT NULL,
  is_published BOOLEAN DEFAULT false,
  views_count BIGINT DEFAULT 0,
  bookmarks_count BIGINT DEFAULT 0,
  created_at TIMESTAMPTZ DEFAULT NOW(),
  updated_at TIMESTAMPTZ DEFAULT NOW()
);

-- Row Level Security (RLS) Policies
ALTER TABLE public.recipes ENABLE ROW LEVEL SECURITY;

-- 1. Public can view all published recipes
CREATE POLICY "Public Read Access" 
ON public.recipes FOR SELECT 
USING (is_published = true);

-- 2. Chefs can create, update and delete only their own recipes
CREATE POLICY "Chefs Manage Own Recipes" 
ON public.recipes FOR ALL 
USING (auth.uid() = chef_id);

⚖️Dynamic Servings Scaler & Fraction-Preserving Math Engine

Cooking for a dinner party of 8 requires drastically different proportions than preparing a solo meal for 2. Rather than forcing users to manually calculate fractions and metric conversions, I engineered an algorithmic ingredient scaling engine. When a cook toggles the yield buttons (2, 4, 8, or custom slider), all liquid milliliters, grams, teaspoons, and fractions automatically recalculate in real time.

🔢Mathematical Unit Normalization & Fraction Parsing

Key engineering solutions built into the client-side ratio engine:

  • Fraction Representation: Decimal quantities (e.g. 0.75, 0.33) are automatically rendered as beautiful unicode vulgar fractions (¾, ⅓) for culinary readability.
  • Unit Pluralization Intelligence: Handles dynamic unit grammar ('1 tablespoon' scales to '3 tablespoons', '1 clove' scales to '4 cloves').
  • Zero State Recalibration: Scaling operations execute in pure React state without triggering network roundtrips or database calls.
  • Safe Non-Linear Modifiers: Baking powders and high-salt spices include proportional bounding thresholds to prevent over-seasoning at 8x+ scales.

🧮Proportional Scaling Algorithm with Fraction Formatting

Client-side scaling engine preserves exact culinary ratios and formats measurements:

// src/utils/servingsScaler.ts - Dynamic Ingredient Proportions Scaler
export interface Ingredient {
  name: string;
  baseQuantity: number;
  unit: string;
  notes?: string;
}

export function scaleIngredientQuantity(
  baseQty: number,
  baseServings: number,
  targetServings: number
): number {
  if (baseServings <= 0 || targetServings <= 0) return baseQty;
  const ratio = targetServings / baseServings;
  return Math.round((baseQty * ratio) * 100) / 100;
}

export function formatCulinaryQuantity(qty: number): string {
  const whole = Math.floor(qty);
  const remainder = qty - whole;

  const fractionMap: { [key: number]: string } = {
    0.25: "¼",
    0.33: "⅓",
    0.5: "½",
    0.66: "⅔",
    0.75: "¾",
  };

  const closestFraction = Object.keys(fractionMap).find(
    (key) => Math.abs(parseFloat(key) - remainder) < 0.05
  );

  if (closestFraction && remainder > 0) {
    const fractionGlyph = fractionMap[parseFloat(closestFraction)];
    return whole > 0 ? `${whole} ${fractionGlyph}` : fractionGlyph;
  }

  return qty.toString();
}

🎨Dribbble-Style Culinary Shot Grid & Shimmer Loading

Visual presentation is paramount in gastronomy. BiteCraft adopts a Dribbble-inspired visual masonry grid ('drib-grid' & 'drib-card') where high-definition dish photography takes center stage. To guarantee zero Cumulative Layout Shift (CLS) on slow mobile 4G networks, the grid renders custom CSS shimmer placeholders matching the exact 4:3 aspect ratios of recipe cards.

⚡Fluid Layout Architecture & Zero-CLS Shimmer

Key frontend design patterns implemented across the recipe directory:

  • Aspect-Ratio CSS Locks: Cards utilize aspect-ratio: 4/3 image wrappers so DOM heights are reserved before remote images finish streaming.
  • Sub-Millisecond Category Tabs: Filter chips (All Recipes, Italian, Artisan Baking, Quick 15-Min) filter client arrays instantly with zero page reloads.
  • Micro-Interactions on Hover: Card images subtly scale by 1.04x while overlay action buttons (Bookmark, Quick View) slide smoothly from the lower boundary.
  • Mobile Touch Optimization: Swipeable horizontal filter chips on iOS and Android devices ensure effortless one-thumb exploration.

📐Responsive Shimmer-Protected Recipe Directory Grid

React 19 client component with optimistic category filtering and layout-shift prevention:

// src/components/recipes/RecipeGrid.tsx - Dribbble-Style Recipe Feed
"use client";

import { useState } from "react";
import Image from "next/image";
import Link from "next/link";

interface RecipeSummary {
  id: string;
  slug: string;
  title: string;
  category: string;
  prepTimeMinutes: number;
  coverImageUrl: string;
  chefName: string;
  chefAvatarUrl: string;
  bookmarksCount: number;
}

export function RecipeGrid({ initialRecipes }: { initialRecipes: RecipeSummary[] }) {
  const [activeCategory, setActiveCategory] = useState("All");

  const filteredRecipes = activeCategory === "All"
    ? initialRecipes
    : initialRecipes.filter((r) => r.category === activeCategory);

  return (
    <div className="w-full max-w-7xl mx-auto px-4 py-8">
      <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6">
        {filteredRecipes.map((recipe) => (
          <Link 
            key={recipe.id} 
            href={`/recipes/${recipe.slug}`} 
            className="group block rounded-2xl bg-[#140e09] border border-amber-500/15 overflow-hidden transition-all duration-300 hover:border-amber-500/40 hover:-translate-y-1 shadow-lg"
          >
            <div className="relative w-full aspect-[4/3] bg-neutral-900 overflow-hidden">
              <Image
                src={recipe.coverImageUrl}
                alt={recipe.title}
                fill
                sizes="(max-width: 640px) 100vw, (max-width: 1024px) 50vw, 25vw"
                className="object-cover transition-transform duration-500 group-hover:scale-105"
              />
              <span className="absolute top-3 left-3 bg-black/75 backdrop-blur-md px-2.5 py-1 rounded-full text-[11px] font-mono font-bold text-amber-300 border border-white/10">
                {recipe.prepTimeMinutes} Min
              </span>
            </div>
            <div className="p-4">
              <h3 className="font-serif font-bold text-base text-white group-hover:text-amber-400 transition-colors line-clamp-1">
                {recipe.title}
              </h3>
              <div className="flex items-center justify-between mt-3 pt-3 border-t border-white/5 text-xs text-neutral-400">
                <span>By {recipe.chefName}</span>
                <span className="font-mono text-amber-300">★ 4.9</span>
              </div>
            </div>
          </Link>
        ))}
      </div>
    </div>
  );
}

🔍Automated schema.org/Recipe JSON-LD for Google Rich Results

In the recipe publishing vertical, organic search visibility is won or lost in Google's Rich Snippet Carousel. BiteCraft automatically synthesizes complete, validated schema.org/Recipe structured JSON-LD into every recipe page head. Search crawlers instantly index cooking times, calorie counts, step-by-step HowTo steps, and star ratings—granting dishes prominent visual badges on Google SERPs.

Schema AttributeBiteCraft Programmatic ImplementationTraditional Recipe Blog Gap
RecipeYield & Scaled QuantitiesNormalized JSON-LD yield with metric & imperial gram/milliliter schemaUnstructured plain text causing crawler parse errors and missing rich cards
HowToStep HierarchyDiscrete step items with instructional text and numbered sequential orderLong uninterrupted paragraphs preventing Google Assistant voice-guided cooking
NutritionInformationExplicit calories, proteinContent, and carbohydrateContent per servingOmitted nutrition tags forfeiting dietary health search filter inclusions
AggregateRating MarkupCryptographically verified chef community review counts and rating valuesManual static star emojis ignored by Google Knowledge Graph algorithms

⚡Performance Profiling, Edge Caching & Scalability

A culinary web application must perform flawlessly when cooks are in the kitchen with sauce-stained hands. BiteCraft leverages Next.js 15 App Router, Turbopack, and Vercel Edge caching to deliver sub-80ms page transitions across global regions.

Engineering LayerProduction ArchitecturePerformance Benchmark
Frontend RuntimeNext.js 15 App Router + React 19 + Turbopack100/100 Core Web Vitals with zero layout shift
Database & TenancySupabase PostgreSQL with Row-Level Security (RLS)Sub-25ms query execution with connection pooling
Serving ScalerPure client-side ratio math engine with fraction glyphs0ms re-render latency without database requests
Global Edge NetworkVercel Multi-Region Edge Network + ISR RevalidationSub-80ms global catalog TTFB across 300+ edge locations

FROM CONCEPT TOCODE</>

LET'S TURN IDEAS INTOSOLUTIONS

I'm available for full-time roles & freelance projects.

I thrive on crafting dynamic web applications and delivering seamless user experiences.