Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/Miguelcds/Recipe-Hub/llms.txt

Use this file to discover all available pages before exploring further.

Clicking a recipe card navigates to /recipe/:id, where the full recipe is displayed — image, category, ingredients, instructions, and an optional video tutorial.

Route and data fetching

The RecipeDetail page reads the id parameter from the URL using React Router’s useParams, then passes it to the useRecipeDetail hook to load the recipe.
import React from "react"
import { useParams } from "react-router-dom"
import useRecipeDetail from "../hooks/useRecipeDetail"
import RecipeDetailCard from "../components/RecipeDetailCard"

const RecipeDetail = () => {
  const { id } = useParams()
  const { recipe, loading, apiError } = useRecipeDetail(id)

  if (loading) return <p> Cargando... </p>
  if (apiError) return <p style={{ color: "red" }}>{apiError}</p>
  if (!recipe) return null

  return <RecipeDetailCard recipe={recipe} />
}

export default RecipeDetail
The hook re-runs whenever id changes, so navigating between recipe pages always loads fresh data.

Recipe object shape

The getRecipeById API call returns a recipe object with the following structure:
FieldTypeDescription
idstringUnique recipe identifier
namestringRecipe name
picturestringURL of the recipe image
categorystringMeal category
instructionsstringFull cooking instructions
videostring | nullYouTube URL for the tutorial, or null if unavailable
ingredientsarrayList of ingredient objects
Each entry in ingredients has:
FieldTypeDescription
namestringIngredient name
measurestringQuantity and unit (e.g. “2 tbsp”)

RecipeDetailCard component

RecipeDetailCard renders all the recipe content. It also connects to the favorites system via the useFavorites hook.
RecipeDetailCard.jsx
import ReactPlayer from "react-player"
import { useFavorites } from "../context/FavoritesContext"
import "./RecipeDetailCard.css"

const RecipeDetailCard = ({ recipe }) => {
  const { isFavorite, toggleFavorite } = useFavorites()
  return (
    <div className="recipe-detail">
      <img src={recipe.picture} alt="" />
      <h3>{recipe.name}</h3>
      <p>{recipe.category}</p>
      <h5>Ingredients:</h5>
      <ul style={{ listStyle: "none" }}>
        {recipe.ingredients?.map((ig, i) => (
          <li key={i}>
            {ig.name} - {ig.measure}
          </li>
        ))}
      </ul>
      <ReactPlayer src={recipe.video} controls width="100%" height="400px" />
      <h4>{recipe.instructions}</h4>
      <button onClick={() => toggleFavorite(recipe.id)}>
        {isFavorite(recipe.id) ? "💔 Remove from Favs" : "❤️ Add to Favs"}
      </button>
    </div>
  )
}

export default RecipeDetailCard

UI sections

The detail page is laid out in the following order:
1

Recipe image

The meal thumbnail (recipe.picture) is rendered as an <img> at the top.
2

Name and category

The recipe name appears as a <h3> heading, followed by the category as a <p> element.
3

Ingredients list

An unordered list renders each ingredient as {ig.name} - {ig.measure} — for example, “Olive Oil - 2 tbsp”.
4

Video player

A ReactPlayer is rendered unconditionally using the recipe.video YouTube URL and src prop. The player is 100% wide and 400px tall with controls enabled.
5

Instructions

The full cooking instructions are displayed as a <h4> element.
6

Favorites button

A button toggles the recipe in/out of favorites. When already saved it reads ”💔 Remove from Favs”; when not saved it reads “❤️ Add to Favs”. See Favorites for details.

Video playback

Recipe Hub uses ReactPlayer to embed YouTube video tutorials. It uses the src prop (not url) and renders with controls, fixed at 400px height:
<ReactPlayer src={recipe.video} controls width="100%" height="400px" />
The player is always rendered in the component — it is not conditionally hidden when the video field is empty.

Build docs developers (and LLMs) love