Connecting relational data from Airtable using Gridsome and GraphQL queries

I’m trying to link related data in my Gridsome project that uses Airtable for the data source. I have a Furniture table and a Designers table in my Airtable setup. Each furniture record includes a “designers” field, which holds the designer’s ID who created that piece. My goal is to use this ID to fetch the designer’s complete information from the Designers table and create a relational query.

Here’s my gridsome.config.js:

module.exports = {
  siteName: 'Furniture Store',
  plugins: [
    {
      use: '@gridsome/source-airtable',
      options: {
        apiKey: 'keyhMlUJl9q3uzk0b',
        baseId: 'appkEp5El5UHrgnks',
        tableName: 'Furniture',
        typeName: 'Product',
      }
    },
    {
      use: '@gridsome/source-airtable',
      options: {
        apiKey: 'keyhMlUJl9q3uzk0b',
        baseId: 'appkEp5El5UHrgnks',
        tableName: 'Designers',
        typeName: 'Designers',
      }
    },
  ],
  templates: {
    Designers: '/designer/:id'
  }
}

My main page (Index.vue):

<template>
  <Layout>
    <h1>Furniture Store</h1>
    <ProductCard
      v-for="product in $page.allProduct.edges"
      :key="product.node.id"
      :product="product"
    />
  </Layout>
</template>

<page-query>
query {
  allProduct {
    edges {
      node {
        id
        name
        designer
        description
        type
        inStock
        images {
          thumbnails {
            large {
              url
              width
              height
            }
          }
        }
      }
    }
  }
}
</page-query>

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

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

In my ProductCard.vue component:

<template>
    <v-app>
        <v-card class="mx-auto my-12" max-width="374">
            <v-img
            height="250"
            :src="product.node.images[0].thumbnails.large.url"
            ></v-img>
            <v-card-title>{{ product.node.name }}</v-card-title>
            <v-card-text>
                <v-row align="center" class="mx-0">
                    <v-rating
                    :value="4.5"
                    color="amber"
                    dense
                    half-increments
                    readonly
                    size="14"
                    ></v-rating>
                    <div class="grey--text ml-4">4.5 (413)</div>
                </v-row>
                <div class="my-4 subtitle-1 black--text">
                    {{ product.node.description }}
                </div>
                <g-link to="/">Link to Designer</g-link>
            </v-card-text>
            <v-divider class="mx-4"></v-divider>
            <v-card-title>Tonight's availability</v-card-title>
        </v-card>
    </v-app>
</template>

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

And my Designer.vue template:

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

<page-query>
query Designer($id: ID!) {
  designers(id: $id) {
    name
    id
    bio
  }
}
</page-query>

Any guidance on how to properly set up this relationship to access the designer details through the designer ID from the furniture table would be greatly appreciated!

theres another way - use the @refers directive in your schema. add this to gridsome.server.js: api.loadSource(actions => { actions.addSchemaResolvers({ Product: { designer: { type: 'Designers', resolve: (obj, args, { graphql }) => graphql.getNodeById('Designers', obj.designer) } } }) }) then you can query like designer { name bio } instead of just the designer field. way cleaner than manual lookups.

Your issue is that Gridsome’s Airtable plugin doesn’t auto-create GraphQL relationships between tables. You’ll need to set these up manually using gridsome.server.js. Create a gridsome.server.js file in your project root: javascript module.exports = function (api) { api.createPages(({ createPage, graphql }) => { // This runs after all data is loaded }); api.loadSource(({ addCollection, getCollection }) => { const products = getCollection('Product'); const designers = getCollection('Designers'); products.data().forEach(product => { if (product.designer) { const designerId = Array.isArray(product.designer) ? product.designer[0] : product.designer; product.designerDetails = designers.findNode({ id: designerId }); } }); }); }; Then update your page query to grab the designer details: graphql query { allProduct { edges { node { id name designer designerDetails { name bio id } description type inStock images { thumbnails { large { url width height } } } } } } } } This creates the relationship manually so you can access designer info directly in your components without extra queries.