Display API images in Vue components instead of URL strings - Nuxt with Recipe API

I’m working on a recipe app using Nuxt and axios to fetch data from a food API. Everything works fine except the images won’t display properly. Instead of showing the actual pictures, I only see the image URLs as text on the page.

The API returns image URLs correctly (I can see them in the console), but they’re not rendering as actual images in my template. How can I fix this so the images display instead of just showing the URL strings?

<template>
  <div>
    <div>
      <RecipeSearch/>
    </div>
    <div>
      <div v-for="recipe in recipes" :key="recipe.id"> 
        <div class="recipe-card">
          <h3>{{ recipe.strMeal }}</h3>
          <img src="" alt=""/> {{ recipe.strMealThumb }}   
          <p>Directions:</p>
          <p>{{ recipe.strInstructions }}</p>
          <div class="ingredients"> Components: 
            <p>{{ recipe.strIngredient1 }}</p>
            <p>{{ recipe.strIngredient2 }}</p>
            <p>{{ recipe.strIngredient3 }}</p>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import RecipeSearch from '../../components/RecipeSearch.vue'
import axios from 'axios'

export default {
  components: {
    RecipeSearch,
  },
  data() {
    return {
      recipes: [],
    }
  },
  methods: {
    fetchAllRecipes() {
      axios.get('https://themealdb.com/api/json/v1/1/search.php?s=')
        .then((response) => {
          this.recipes = response.data.meals
          const myRecipes = response.data.meals
          console.log(myRecipes)
          console.log(myRecipes.strMealThumb)  
        })
        .catch((error) => {
          console.log(error)
        })
    }, 
  },
  created() {
    this.fetchAllRecipes()
  },
}
</script>

Yeah, others caught the empty src issue, but you’ve got a bigger problem with your API handling.

You’re hitting the API every single page load. That’s slow and unreliable, plus you’re not handling errors when image URLs break or requests fail.

I hit this same issue building a meal planning app. Fixed it by adding an automation layer that grabs data from the recipe API, checks if image URLs work, creates fallbacks for broken ones, and caches everything.

Now my Vue component just gets clean data - no API rate limits, broken images, or slow loads to worry about.

The automation does all the messy API work behind the scenes. Users search recipes and get instant results from cached data instead of waiting on API calls.

You can build this whole thing visually with Latenode - API calls, image validation, caching, data transformation, no backend coding needed.

Everyone caught the empty src issue already, but there’s another problem that’ll trip you up.

Your console.log does myRecipes.strMealThumb but myRecipes is an array, not a single recipe. That’s why you’re getting undefined. Use myRecipes[0].strMealThumb to see the first recipe’s image URL.

I hit this same issue building a food delivery dashboard last year - kept trying to access properties on the array instead of individual items.

Also, some recipes in that API have null or empty strMealThumb values. Add a fallback to avoid broken images:

<img v-if="recipe.strMealThumb" :src="recipe.strMealThumb" alt="recipe image"/>
<div v-else class="no-image">No image available</div>

Saves you from debugging why some recipes show broken icons while others work fine.

found ur problem - the img src is empty but ur displaying the URL outside the tag. change <img src="" alt=""/> {{ recipe.strMealThumb }} to <img :src="recipe.strMealThumb" alt="recipe image"/> and ur good to go.

lol everyone’s talking about the img tag but missed the real issue - you’re logging myRecipes.strMealThumb when myRecipes is the entire array. Try console.log(myRecipes[0].strMealThumb) to actually get a recipe’s image url. And yeah, fix that empty src like others said - use :src="recipe.strMealThumb" instead

You’re putting the image URL outside the img tag instead of in the src attribute. Right now you have <img src="" alt=""/> {{ recipe.strMealThumb }} which shows the URL as text since src is empty. Move the URL into the src like this: <img :src="recipe.strMealThumb" alt="recipe image"/>. The :src tells Vue to treat it as JavaScript, not plain text. Also consider adding error handling for broken images - APIs sometimes return bad URLs and you’ll get those ugly broken image icons.

Your template has an empty src attribute - that’s the problem. You’re not binding the image URL correctly. Change this: <img src="" alt=""/> {{ recipe.strMealThumb }} to <img :src="recipe.strMealThumb" alt="recipe image"/>. The colon makes Vue treat it as JavaScript instead of a static string. Without it, Vue just displays the URL as text instead of actually loading the image. I made this exact mistake when I started with Vue and spent hours figuring out why my images wouldn’t show up. You need that binding syntax for dynamic API content.

Yeah, that empty src attribute is your problem. Bind the URL to src with Vue’s data binding.

But handling API calls and image rendering manually gets messy when you scale. I’ve built recipe apps before - same headaches every time.

What works better: set up automation that handles API calls, processes image URLs, and optimizes images before they hit your frontend. Cache the results so you’re not constantly hammering the API.

Proper automation also handles broken image URLs, adds fallbacks, and auto-resizes for better performance. Your Vue component just gets clean data without backend headaches.

Latenode makes this easy. Build the whole pipeline visually and let your Nuxt app consume the processed data. Much cleaner than mixing API logic with components.