"use client"; import { useState } from 'react'; type Analysis = { platform: 'tiktok' | 'instagram' | 'unknown'; analysis: { ingredients: Array<{ name: string; quantity: string | null; unit: string | null; notes?: string | null }>; prep_steps: string[]; cooking_steps: string[]; }; description?: string; transcript?: string; thumbnailBase64?: string; title?: string; }; export default function RecipeAnalyzerPage() { const [url, setUrl] = useState(''); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const [result, setResult] = useState(null); const [saving, setSaving] = useState(false); const canSave = !!result && !!url; async function onSubmit(e: React.FormEvent) { e.preventDefault(); setLoading(true); setError(null); setResult(null); try { const res = await fetch('/api/analyze', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ url }), }); const data = await res.json(); if (!res.ok) throw new Error(data?.error || 'Failed'); setResult(data); } catch (err: any) { setError(err?.message || 'Something went wrong'); } finally { setLoading(false); } } async function onSave() { if (!result) return; setSaving(true); try { const res = await fetch('/api/recipes', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ url, platform: result.platform, title: result.title || '', description: result.description || '', transcript: result.transcript || '', analysis: result.analysis, thumbnailBase64: result.thumbnailBase64, }), }); const data = await res.json(); if (!res.ok) throw new Error(data?.error || 'Failed to save'); alert('Saved!'); } catch (err: any) { alert(err?.message || 'Failed to save'); } finally { setSaving(false); } } return (

Recipe AI from Reels/TikToks

Paste a TikTok or Instagram share link. The AI analyzes only the video to extract an ingredient list, prep steps, and cooking steps.

setUrl(e.target.value)} className="w-full rounded border border-neutral-300 dark:border-neutral-700 bg-transparent px-3 py-2" /> {result && ( )}
{error && (
{error}
)} {result && (
setResult({ ...result, title: e.target.value })} className="w-full rounded border border-neutral-300 dark:border-neutral-700 bg-transparent px-3 py-2" placeholder="Recipe title" />
{result.thumbnailBase64 && ( thumbnail )}
Source:{' '} {url}
{result.description && (
Description: {result.description}
)}

Ingredients

    {result.analysis.ingredients.map((it, idx) => (
  • {it.name} {it.quantity ? ` – ${it.quantity}` : ''} {it.unit ? ` ${it.unit}` : ''} {it.notes ? ` (${it.notes})` : ''}
  • ))}

Prep Steps

    {result.analysis.prep_steps.map((s, i) => (
  1. {s}
  2. ))}

Cooking Steps

    {result.analysis.cooking_steps.map((s, i) => (
  1. {s}
  2. ))}
)}
); }