Connecting related tables in Gridsome with Airtable and GraphQL queries

I’m working on a project where I need to connect two Airtable databases through Gridsome. I have a Books table that contains an “authors” field with the ID of the person who wrote each book. The authors have their own separate table with detailed information. I want to fetch both the book data and the related author information in my GraphQL queries. How can I set up these relationships properly?

My gridsome.config.js setup:

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

Home.vue component:

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

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

<script>
import BookDisplay from '~/components/BookDisplay';

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

components/BookDisplay.vue:

<template>
    <v-app>
        <v-card
        class="mx-auto my-12"
        max-width="374"
    >
            <v-img
            height="250"
            :src="book.node.covers[0].thumbnails.large.url"
            ></v-img>

            <v-card-title>{{ book.node.title }}</v-card-title>

        <v-card-text>
        <v-row
            align="center"
            class="mx-0"
        >
            <v-rating
            :value="4.2"
            color="amber"
            dense
            half-increments
            readonly
            size="14"
            ></v-rating>

            <div class="grey--text ml-4">4.2 (285)</div>
        </v-row>

        <div class="my-4 subtitle-1 black--text">
            {{ book.node.summary }}
        </div>

          <g-link to="/">View Author Details</g-link>
        </v-card-text>

        <v-divider class="mx-4"></v-divider>

        <v-card-title>Current Status</v-card-title>
    </v-card>
    </v-app>
</template>

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

templates/Author.vue:

 <template>
   <h1>{{ $page.authors.name }}</h1>
 </template>

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

Any guidance would be really helpful. Thanks in advance!

First, create a gridsome.server.js file in your project root and set up your collection references there. You’ll need to establish the relationship between BookItem and Authors collections using the collection API. In your server API hook, add collection.addReference('author', 'Authors') to your BookItem collection. This tells Gridsome the author field should resolve to the Authors collection. Once that’s done, your GraphQL query can pull nested author data directly through the relationship. Just make sure your Airtable author field has the actual record ID from the Authors table - not just text.

Hey! Use the @reference directive in GraphQL. In gridsome.server.js, add api.createReference('BookItem', 'Authors'). Then change author to author @reference in your query to pull all author data. Works great!

You’re close, but missing one key thing. Gridsome doesn’t automatically know your author field should link to the Authors collection. You need to add references: { author: 'Authors' } to your Books plugin options in gridsome.config.js. This tells the Airtable plugin to treat the author field as a reference to your Authors collection instead of plain text. Then your GraphQL query can access nested author data like author { name biography } instead of just the raw ID. Had this exact same issue last month - this fixed it right away. Just make sure your Airtable author field is actually a linked record field pointing to your Authors table, not text input.