Connecting related data between Airtable tables in Gridsome with GraphQL queries

I’m working on a project using Gridsome with Airtable as my data source. I have two separate tables in Airtable - one for books and another for authors. The books table contains an “author” field that stores the ID of the author from the authors table.

I need help figuring out how to create a GraphQL query that can fetch both the book information and the related author details using that ID connection. Right now I can only get data from one table at a time.

Here’s my current setup:

gridsome.config.js

module.exports = {
  siteName: 'Book Library',
  plugins: [
    {
      use: '@gridsome/source-airtable',
      options: {
        apiKey: 'keyAbc123XYZ789',
        baseId: 'appDef456GHI012',
        tableName: 'Books',
        typeName: 'Book',
      }
    },
    {
      use: '@gridsome/source-airtable',
      options: {
        apiKey: 'keyAbc123XYZ789',
        baseId: 'appDef456GHI012',
        tableName: 'Authors',
        typeName: 'Author',
      }
    },
  ],
  templates: {
    Author: '/author/:id'
  }
}

pages/Index.vue

<template>
  <Layout>
    <h1>My Book Collection</h1>
    <BookItem
      v-for="book in $page.allBook.edges"
      :key="book.node.id"
      :book="book"
    />
  </Layout>
</template>

<page-query>
query {
  allBook {
    edges {
      node {
        id
        title
        author
        summary
        genre
        available
        covers {
          thumbnails {
            large {
              url
              width
              height
            }
          }
        }
      }
    }
  }
}
</page-query>

<script>
import BookItem from '~/components/BookItem'

export default {
  components: {
    BookItem
  }
}
</script>

components/BookItem.vue

<template>
  <div class="book-card">
    <img :src="book.node.covers[0].thumbnails.large.url" alt="Book cover" />
    <h3>{{ book.node.title }}</h3>
    <p>{{ book.node.summary }}</p>
    <g-link to="/">View Author Details</g-link>
  </div>
</template>

<script>
export default {
  name: 'BookItem',
  props: {
    book: {
      type: Object,
      required: true,
    },
  },
}
</script>

templates/Author.vue

<template>
  <div>
    <h1>{{ $page.author.name }}</h1>
    <p>{{ $page.author.biography }}</p>
  </div>
</template>

<page-query>
query Author($id: ID!) {
  author(id: $id) {
    name
    id
    biography
  }
}
</page-query>

Any suggestions would be really helpful!

Had the same issue building a recipe site with ingredients and categories. The references approach mentioned above works, but check your field mapping in GraphQL playground first. Your Airtable author field needs to be ‘Link to another record’ pointing to your Authors table - not just text with IDs. If it’s text right now, convert it in Airtable first. After adding references config, do a full dev server restart. Gridsome won’t pick up schema changes otherwise. Test your relationships at http://localhost:8080/___explore to see if the author object nests properly under each book. Watch out for books with empty or invalid author references - they might disappear from query results depending on your structure. Add error handling for books without authors if that’s possible in your data.

You need to set up references between your tables so Gridsome can automatically create the GraphQL relationships.

Add a references field to your Books table config:

{
  use: '@gridsome/source-airtable',
  options: {
    apiKey: 'keyAbc123XYZ789',
    baseId: 'appDef456GHI012',
    tableName: 'Books',
    typeName: 'Book',
    references: {
      author: 'Author'
    }
  }
}

This tells Gridsome that the author field in your Books table should reference the Author type.

Then your GraphQL query becomes:

query {
  allBook {
    edges {
      node {
        id
        title
        summary
        genre
        available
        author {
          name
          biography
          id
        }
        covers {
          thumbnails {
            large {
              url
              width
              height
            }
          }
        }
      }
    }
  }
}

I ran into this exact problem building a product catalog with related categories. The references config is what makes it work. Without it, you’re stuck with raw ID values.

Just make sure your Airtable author field actually links to records in the Authors table - not just text values.

First, check your Airtable field structure - make sure the author field in your Books table is actually a linked record field, not just text with IDs. Then you’ll need to handle how Airtable returns linked records as arrays. Access the first linked author with author[0] since Airtable always returns arrays even for single links. I ran into this same issue on a project with products and suppliers. Update your BookItem component to use book.node.author[0].name instead of book.node.author. Also check if some books have multiple authors - you’d need to map through the array for those. The GraphQL playground will show you the exact structure once you add the references config and restart your dev server.