Vue.js lazy loading plugin not functioning with Airtable image data

I need help figuring out how to properly set up lazy loading for images coming from Airtable using Vue.js.

I’m building a website that pulls image data from my Airtable database and displays it using Vue. Right now I have this code that works fine for showing images:

<img class="lazyload" id="picture1" :src="record['fields']['Image'][0]['thumbnails']['full']['url']" alt="" v-if="record['fields']['Image']">

The problem is that I added a lazy loading library but it’s not working at all. All the images still load right when the page opens instead of waiting until they’re needed. I think the issue is that I need to use ‘data-src’ instead of ‘:src’ for the lazy loading to work properly.

When I change my code to this, no images show up:

<img class="lazyload" id="picture1" :data-src="record['fields']['Image'][0]['thumbnails']['full']['url']" alt="" v-if="record['fields']['Image']">

I’m pretty new to both Vue and Airtable so I’m not sure what I’m doing wrong. Has anyone dealt with this before? Thanks for any suggestions!

Been down this road before with external APIs. The issue is Vue’s reactivity system.

When you use :data-src, Vue tries to bind it as a reactive property, but your lazy loading library expects a plain HTML attribute called data-src.

Try this instead:

<img class="lazyload" id="picture1" :data-src="record['fields']['Image'][0]['thumbnails']['full']['url']" alt="" v-if="record['fields']['Image']">

Wait, that’s what you tried. The real problem is timing. Your lazy loading library probably initializes before Vue renders the images.

I fixed this exact issue by manually triggering the lazy loader after Vue updates the DOM:

this.$nextTick(() => {
  // Reinitialize your lazy loading library here
  // For example, if using lazysizes: window.lazySizes.init();
});

Put this in your component’s updated() lifecycle hook or after you fetch data from Airtable.

Alternatively, use v-lazy directive if your library supports it, or switch to a Vue specific lazy loading solution like vue-lazyload.

Deal with this constantly at work. Your lazy loading library gets confused when images show up after the initial DOM scan.

I use a watcher to reinitialize the lazy loader whenever Airtable data changes:

watch: {
  records: {
    handler() {
      this.$nextTick(() => {
        // Force lazy loader to rescan for new images
        if (window.lazySizes) window.lazySizes.autoSizer.checkElems();
        // Or whatever method your library uses
      });
    },
    deep: true
  }
}

For HTML, use regular data-src without Vue binding:

<img class="lazyload" :data-src="record['fields']['Image'][0]['thumbnails']['full']['url']" alt="" v-if="record['fields']['Image']">

Watcher fires every time Airtable data updates and tells the lazy loader to scan for new images. Way more reliable than timing it manually after API calls.

Which lazy loading library are you using? The rescan method name varies.

Classic issue - your lazy loading library loads before the Airtable data shows up. I’ve hit this exact problem with dynamic content from external APIs. Most lazy loading libraries only scan for images once when they initialize. Since your Airtable images aren’t in the DOM yet, they never get registered.

I stopped fighting with data-src binding and handled lazy loading directly in Vue instead:

<img class="lazyload" :src="shouldLoad ? record['fields']['Image'][0]['thumbnails']['full']['url'] : ''

Then I used an intersection observer or scroll listener in the Vue component to flip shouldLoad to true when needed. You get full control over when images load without depending on external libraries that weren’t built for dynamic Vue content. Same performance boost, but no timing or DOM binding headaches.

yeah, same thing happened to me. use the v-lazy-image directive instead of mixing Vue with regular lazy loading libraries - most of those don’t play well with Vue’s rendering cycle. or do a quick manual check: drop a console.log right after your airtable data loads to see if the img elements are actually in the DOM when the lazy loader runs. i bet they’re not.

Had the same issue mixing lazy loading with external API content. The problem is lazy loading libraries scan the DOM once during setup, but your Airtable images get added later when Vue updates.

This fixed it for me - use v-bind without the colon for data-src:

<img class="lazyload" v-bind="{ 'data-src': record['fields']['Image'][0]['thumbnails']['full']['url'] }" alt="" v-if="record['fields']['Image']">

This way the attribute gets set as regular HTML instead of going through Vue’s reactivity.

You also need to call your lazy loading library’s observer or refresh method after the Airtable data loads. Most have something like observer.observe() or refresh() that you can trigger in your .then() block. Skip this and the library won’t see your new images.