How to integrate Airtable records with Vue.js components

I’m struggling to display Airtable records in my Vue.js app and need some guidance. I’ve been working on this for several hours but can’t get the data to show up properly in my template. I’m using the official Airtable JavaScript library to fetch records from my base.

Here’s my current setup:

<template>
  <div class="dashboard-wrapper">
    <div class="content-container">
      <h2>{{ title }}</h2>
      <div class="data-grid">
        <UserCard />
        <div class="items-list">
          <div v-for="entry in dataEntries" :key="entry.id" class="list-item">
            Information: {{ entry }}
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import UserCard from "./UserCard.vue";
import Airtable from "airtable";

export default {
  name: "Dashboard",
  components: {
    UserCard,
  },
  props: {
    title: String,
  },
  data() {
    return {
      dataEntries: [],
    };
  },
  mounted() {
    const database = new Airtable({ apiKey: "your_api_key" }).base(
      "your_base_id"
    );

    database("Main Table")
      .select({
        view: "Default View",
      })
      .firstPage(function (error, results) {
        if (error) {
          console.error(error);
          return;
        }
        results.forEach((result) => {
          console.log(result.get("Title"));
          return result.get("Title");
        });
      });
  },
};
</script>

The data appears in the console but doesn’t populate my Vue component. What am I missing here?

One thing I don’t see mentioned - your template’s rendering {{ entry }} which just dumps the raw object. You’ll need to fix that even after sorting out the data assignment. I hit this same issue building a CMS with Airtable. Once you get the data loading properly, update your template to grab specific properties: vue <div v-for="entry in dataEntries" :key="entry.id" class="list-item"> Information: {{ entry.title }} </div> Definitely add error handling for empty fields too. Airtable records can have missing values and Vue crashes if you try accessing undefined properties. Found this out the hard way when blank title fields killed my entire component.

You’re fetching data but never actually putting it in your Vue component. The forEach loop processes records but doesn’t store them anywhere Vue can see.

I hit this exact same issue building an inventory tracker with Airtable last year. Wasted half a day staring at blank components.

Just populate the dataEntries array in your callback:

mounted() {
  const database = new Airtable({ apiKey: "your_api_key" }).base(
    "your_base_id"
  );

  database("Main Table")
    .select({
      view: "Default View",
    })
    .firstPage((error, results) => {
      if (error) {
        console.error(error);
        return;
      }
      
      this.dataEntries = results.map(record => ({
        id: record.id,
        title: record.get('Title')
      }));
    });
},

Two changes - arrow function keeps the right this context, and I’m mapping results into your dataEntries array instead of just logging them.

Fix your template too. You’re showing the whole object with {{ entry }}. Switch to {{ entry.title }} once the data’s flowing.

Also add loading state handling. Airtable calls take a few seconds and users see empty content while waiting.

Yeah, jackw nailed it. Just make sure you’re using arrow functions or binding this correctly. Had this exact issue last month - spent hours debugging before realizing the callback lost its context. Also handle your loading states or the template will try rendering before the API responds.

Your callback function isn’t updating Vue’s reactive data - that’s the main problem. I’ve hit this same issue with external APIs in Vue.

Besides fixing the data assignment, wrap your Airtable calls in try-catch blocks. Also throw in a loading indicator since these requests can be slow.

What really helped me was moving all Airtable stuff into a separate service file instead of cramming it in the mounted hook. Makes testing way easier and keeps components clean.

You should also consider async/await over callbacks - much cleaner when you’re chaining multiple Airtable operations.

Your callback function isn’t hooked into Vue’s reactivity system. I hit this same issue building a project management dashboard with Airtable - data showed in console but components stayed blank.

Your forEach loop just logs values instead of storing them. Push the data into your component’s dataEntries array.

Here’s what worked for me:

mounted() {
  const database = new Airtable({ apiKey: "your_api_key" }).base(
    "your_base_id"
  );

  database("Main Table")
    .select({
      view: "Default View",
    })
    .firstPage((error, results) => {
      if (error) {
        console.error(error);
        return;
      }
      
      // Clear existing data first
      this.dataEntries = [];
      
      results.forEach((record) => {
        this.dataEntries.push({
          id: record.id,
          title: record.get('Title'),
          // grab other fields you need
        });
      });
    });
},

The arrow function keeps the proper this context so Vue can track changes. Once dataEntries gets populated, your template updates automatically.

This approach works solid across multiple projects. Just handle your API key properly - don’t hardcode it in production builds.

Hit this same problem building a CMS interface. Your callback isn’t actually populating the Vue component’s reactive data array - the forEach loop processes records but never assigns them to dataEntries. What saved me was adding error boundaries around the Airtable calls. Network timeouts will leave your component in a broken state without proper error handling. Watch out for Airtable’s rate limiting too - spam their API during dev and you’ll get temporarily blocked. I started caching stuff in localStorage to avoid pointless requests while testing. One last thing: double-check your API key has read permissions for that specific table and view. Wasted a whole afternoon on what turned out to be a permissions problem on Airtable’s end.

classic mistake - you’re not storing the airtable data in your comp. the callback runs but dataEntries stays empty. use this.dataEntries = results.map(...) inside the callback with arrow function syntax so this points to your vue instance. that’s why console shows data but your template doesn’t render anything.

You’re fetching the data but not putting it into your Vue component’s data. The console.log works because you’re calling it inside the callback, but your dataEntries array stays empty.

I hit this same issue when I started mixing Airtable with Vue. You need to assign the results to your reactive data property.

Replace your mounted() method with this:

mounted() {
  const database = new Airtable({ apiKey: "your_api_key" }).base(
    "your_base_id"
  );

  database("Main Table")
    .select({
      view: "Default View",
    })
    .firstPage((error, results) => {
      if (error) {
        console.error(error);
        return;
      }
      
      this.dataEntries = results.map(record => ({
        id: record.id,
        title: record.get('Title'),
        // add other fields you need
      }));
    });
},

Two key changes:

  1. Use arrow function so this refers to your Vue component
  2. Map the results to your dataEntries array instead of just logging them

Now your template will show the actual data instead of raw record objects. You can access entry.title in your v-for loop.