AI
Pass

Build an AI Meal Planner App with AI Pass SDK

Build an AI Meal Planner App with AI Pass SDK

Food and nutrition apps are consistently popular — and an AI-powered meal planner is one of the easiest to build with serious real-world value. This tutorial walks you through building one from scratch with AI Pass SDK.

Step 1: Create Your AI Pass Account & Client ID

  1. Sign up at aipass.one
  2. Go to Developer DashboardOAuth2 Clients
  3. Create a new OAuth2 client for your app
  4. Copy your Client ID (format: client_XXXXXXXX)

Step 2: Build the Meal Planner

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>AI Meal Planner</title>
  <link href="https://aipass.one/aipass-ui.css" rel="stylesheet">
  <style>
    * { box-sizing: border-box; margin: 0; padding: 0; }
    body { font-family: system-ui, sans-serif; background: #f0fdf4; min-height: 100vh; }
    .container { max-width: 750px; margin: 40px auto; padding: 20px; }
    h1 { font-size: 1.9rem; color: #166534; margin-bottom: 8px; }
    .subtitle { color: #4b7c5a; margin-bottom: 28px; }
    .grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
    @media(max-width:600px) { .grid { grid-template-columns: 1fr; } }
    label { font-weight: 600; font-size: 13px; color: #374151; margin-bottom: 5px; display: block; }
    select, input, textarea {
      width: 100%; padding: 10px 12px; border: 1px solid #d1fae5;
      border-radius: 8px; font-size: 14px; background: white;
    }
    textarea { height: 70px; resize: vertical; }
    .full { grid-column: 1/-1; }
    .plan-btn {
      background: #16a34a; color: white; border: none; width: 100%;
      padding: 14px; border-radius: 10px; font-size: 16px; font-weight: 700;
      cursor: pointer; margin-top: 18px; transition: background 0.2s;
    }
    .plan-btn:hover { background: #15803d; }
    #output {
      margin-top: 28px; background: white; padding: 24px;
      border-radius: 12px; border: 1px solid #d1fae5; display: none;
    }
    pre { white-space: pre-wrap; font-family: inherit; line-height: 1.7;
      color: #374151; font-size: 14px; }
    .tabs { display: flex; gap: 8px; margin-bottom: 16px; }
    .tab {
      padding: 8px 16px; border-radius: 6px; cursor: pointer; font-size: 13px;
      background: #f0fdf4; border: 1px solid #d1fae5; font-weight: 600;
    }
    .tab.active { background: #16a34a; color: white; border-color: #16a34a; }
  </style>
</head>
<body>
  <div class="container">
    <h1>🥗 AI Meal Planner</h1>
    <p class="subtitle">Describe your diet and preferences — get a complete weekly meal plan.</p>

    <div class="grid">
      <div>
        <label>Diet Type</label>
        <select id="diet">
          <option value="balanced">Balanced / Omnivore</option>
          <option value="vegetarian">Vegetarian</option>
          <option value="vegan">Vegan</option>
          <option value="keto / low-carb">Keto / Low-Carb</option>
          <option value="Mediterranean">Mediterranean</option>
          <option value="high-protein">High-Protein</option>
          <option value="gluten-free">Gluten-Free</option>
          <option value="paleo">Paleo</option>
        </select>
      </div>
      <div>
        <label>Plan Duration</label>
        <select id="duration">
          <option value="3-day">3 days</option>
          <option value="5-day">5 days (weekdays)</option>
          <option value="7-day" selected>Full week (7 days)</option>
        </select>
      </div>
      <div>
        <label>Number of People</label>
        <select id="people">
          <option value="1 person">Just me</option>
          <option value="2 people" selected>2 people</option>
          <option value="family of 4">Family of 4</option>
          <option value="family of 6">Family of 6</option>
        </select>
      </div>
      <div>
        <label>Cooking Time</label>
        <select id="cooking">
          <option value="quick (under 20 min)">Quick (under 20 min)</option>
          <option value="moderate (30-45 min)" selected>Moderate (30-45 min)</option>
          <option value="no limit">No limit — I enjoy cooking</option>
        </select>
      </div>
      <div class="full">
        <label>Allergies / Foods to Avoid (optional)</label>
        <textarea id="avoid" placeholder="e.g., No nuts, no shellfish, kids won't eat mushrooms..."></textarea>
      </div>
      <div class="full">
        <label>Any other preferences? (optional)</label>
        <textarea id="prefs" placeholder="e.g., Love Asian food. Budget around €60/week. Prefer light dinners."></textarea>
      </div>
    </div>

    <button class="plan-btn" onclick="generatePlan()">Generate My Meal Plan 🥦</button>

    <div id="output">
      <div class="tabs">
        <div class="tab active" onclick="showTab('plan', this)">Meal Plan</div>
        <div class="tab" onclick="showTab('shopping', this)">Shopping List</div>
      </div>
      <div id="plan-content"><pre id="plan-text"></pre></div>
      <div id="shopping-content" style="display:none"><pre id="shopping-text"></pre></div>
    </div>
  </div>

  <script src="https://aipass.one/aipass-sdk.js"></script>
  <script>
    AiPass.initialize({
      clientId: 'YOUR_CLIENT_ID',
      requireLogin: true,
      darkMode: true
    });

    let planData = { plan: '', shopping: '' };

    function showTab(tab, el) {
      document.querySelectorAll('.tab').forEach(t => t.classList.remove('active'));
      el.classList.add('active');
      document.getElementById('plan-content').style.display = tab === 'plan' ? 'block' : 'none';
      document.getElementById('shopping-content').style.display = tab === 'shopping' ? 'block' : 'none';
    }

    async function generatePlan() {
      const diet = document.getElementById('diet').value;
      const duration = document.getElementById('duration').value;
      const people = document.getElementById('people').value;
      const cooking = document.getElementById('cooking').value;
      const avoid = document.getElementById('avoid').value.trim();
      const prefs = document.getElementById('prefs').value.trim();

      document.getElementById('output').style.display = 'block';
      document.getElementById('plan-text').textContent = 'Generating your meal plan...';
      document.getElementById('shopping-text').textContent = '';

      const avoidLine = avoid ? `\nFoods to avoid: ${avoid}` : '';
      const prefsLine = prefs ? `\nAdditional preferences: ${prefs}` : '';

      const planPrompt = `Create a complete ${duration} meal plan for ${people}.

Diet: ${diet}
Cooking time preference: ${cooking}${avoidLine}${prefsLine}

Format:
- Day 1, Day 2... through Day ${duration.split('-')[0]}
- Each day: Breakfast, Lunch, Dinner (+ Snack if relevant)
- Brief recipe note for each meal (key ingredients + method)
- Keep meals varied and interesting`;

      const shoppingPrompt = `Based on this meal plan, create an organized shopping list for ${people}:

[MEAL_PLAN_PLACEHOLDER]

Organize by category:
- Produce
- Protein
- Dairy/Eggs  
- Grains/Pantry
- Condiments/Other

Include quantities.`;

      try {
        // Generate meal plan
        const r1 = await AiPass.generateCompletion({
          model: 'gpt-5-mini',
          temperature: 1,
          max_tokens: 16000,
          messages: [
            { role: 'system', content: 'You are a professional nutritionist and meal planning expert.' },
            { role: 'user', content: planPrompt }
          ]
        });
        planData.plan = r1.choices[0].message.content;
        document.getElementById('plan-text').textContent = planData.plan;

        // Generate shopping list
        const r2 = await AiPass.generateCompletion({
          model: 'gpt-5-mini',
          temperature: 1,
          max_tokens: 16000,
          messages: [
            { role: 'system', content: 'You are a meal planning expert creating organized shopping lists.' },
            { role: 'user', content: shoppingPrompt.replace('[MEAL_PLAN_PLACEHOLDER]', planData.plan) }
          ]
        });
        planData.shopping = r2.choices[0].message.content;
        document.getElementById('shopping-text').textContent = planData.shopping;

      } catch (err) {
        document.getElementById('plan-text').textContent = 'Error: ' + err.message;
      }
    }
  </script>
</body>
</html>

Step 3: Deploy

Option A: Self-host on Netlify, Vercel, GitHub Pages, or your server. No backend needed — SDK handles auth and billing.

Option B: Publish on AI Pass catalog via Developer Dashboard. Use the </> embed button for iframe code to embed on any website.

Revenue

Every meal plan generation = AI credits spent = 50% commission for you. Users with premium diets and larger families will generate more requests — and more revenue for you.

Extension Ideas

  • Save & share plans — let users save their favorite plans
  • Calorie counter — add nutritional info to each meal
  • Recipe deep-dive — click any meal to get full detailed recipe
  • Grocery delivery link — connect to Instacart or local delivery APIs

Try the live version: AI Meal Planner →