---
# System prepended metadata

title: getting AT data to a website!

---

# getting AT data to a website!

## the steps

if you don't have node, git and gatsby installed, check out [these instructions](https://www.gatsbyjs.com/docs/tutorial/part-zero/) to get your machine ready for development. If you just have node and git, enter `npm install -g gatsby-cli` to install the `gatsby-cli`

start up a gatsby project with
```
cd ~/Development
gatsby new my-gatsby-project
cd my-gatsby-project
code .
gatsby develop
```
Then go to [localhost:8000](http://localhost:8000) to see if it's working. 

In your code editor, let's get rid of all the default gatsby pages except the index, so delete all of the files in `/src/pages` except `index.js` (alternatively, you could throw them all in a folder called `/reference/gatsby` if you want to be able to reference them later on.

We are mainly going to emphasize getting the airtable data in for this tutorial, so we'll actually start by doing that.

Let's install the airtable plugin:

```
npm i gatsby-source-airtable
```

Then let's add it to our `gatsby-config.js`, something like


```
{
  resolve: "gatsby-source-airtable",
  options: {
    apiKey: process.env.AIRTABLE_API_KEY,
    tables: [
      {
        baseId: process.env.AIRTABLE_BASE_ID,
        tableName: "MyTable",
      },
    ]
  }
},
```

you'll need to store your environment variables in a `.env.development` file:
```
AIRTABLE_API_KEY=keyxxxxxxxxxxxxx
AIRTABLE_BASE_ID=appxxxxxxxxxxxxx
```
then you'll need to pull these environment variables in to `gatsby-config.js` with `dotenv`. So install it with `npm i dotenv` and then add the following lines at the top of `gatsby-config.js`

```
require("dotenv").config({
  path: `.env.${process.env.NODE_ENV}`,
})
```

now that you've done this, you should be able to stop the server, then run `gatsby develop` and see the Airtable data show up in [GraphiQL](http://localhost:8000/___graphql)

## MAKING AN INDEX OF RECORDS

something like this: 

```
/** @jsx jsx */
import { jsx } from 'theme-ui'
import { graphql } from "gatsby"

export default ({data}) => {
    const allAirtableData = data.allAirtable.edges;
    return (
        <div
          sx={{padding: "4em"}}
        >
            {/* <pre>
                {JSON.stringify(allAirtableData, null, 4)}
            </pre> */}
            {
                allAirtableData.map(({node}) => (
                    <div
                      sx={{width: "100%", textAlign: "center"}}
                    >
                        <a href={`/yokai/${node.recordId}`}
                          sx={{
                            // color: "rgba(0,0,30,.9"
                          }}
                        ><h1
                          sx={{
                            fontFamily: "Avenir Next, sans-serif",
                            fontSize: "3em",
                            fontWeight: "900",
                            color: "rgba(0,0,30,.9)",
                            textDecoration: "none"
                          }}
                        >{node.data.Name}</h1></a>
                    </div>
                ))
            }
        </div>
    )
}

export const query = graphql`
    query {
        allAirtable {
          edges {
            node {
              id
              recordId
              data {
                Description
                mainFeature
                Creator
                Link_to_Project
                secondFeature
                Name
                weight
                type
                mainAttack
                region
                specialAttack
                height
                backgroundColor
                foregroundColor
                canvaCardLink
                canvaCardBack {
                  id
                  thumbnails {
                    large {
                      url
                      width
                      height
                    }
                  }
                }
                canvaCardFront {
                  id
                  thumbnails {
                    large {
                      url
                      width
                      height
                    }
                  }
                }
              }
            }
          }
        }
      }
`
```


## CREATING INDIVIDUAL PAGES 

To create a page per record, we'll need to add to our `gatsby-node.js` file. 

maybe something like this?

```
const { createFilePath } = require(`gatsby-source-filesystem`)
const path = require(`path`)

exports.onCreateNode = ({ node, getNode, actions }) => {
  const { createNodeField } = actions
  if (node.internal.type === `Mdx`) {
    console.log(`found mdx node of type ${node.internal.type}`)
    const fileNode = getNode(node.parent)
    const slugStem = createFilePath({ node, getNode })
    const slugRoot = fileNode.sourceInstanceName
      ? fileNode.sourceInstanceName
      : "content"
    createNodeField({
      node,
      name: `slug`,
      value: `/${slugRoot}${slugStem}`,
    })
    createNodeField({
      node,
      name: `pageType`,
      value: slugRoot,
    })
    createNodeField({
      node,
      name: `title`,
      value: node.frontmatter.title || fileNode.name || "no title",
    })
    createNodeField({
      node,
      name: `mainImage`,
      value: node.frontmatter.mainImage || "/gatsby.jpg",
    })
  }
}

exports.createPages = async ({ graphql, actions, reporter }) => {
  const { createPage } = actions
  const mdxResult = await graphql(`
    query {
      allMdx {
        edges {
          node {
            id
            fields {
              slug
              title
              pageType
            }
            headings(depth: h1) {
              value
            }
          }
        }
      }
    }
  `)

  if (mdxResult.errors) {
    reporter.panicOnBuild('🚨  ERROR: Loading "createPages" query')
  }

  const mdx = mdxResult.data.allMdx.edges
  mdx.forEach(({ node }, index) => {
    console.log(
      `creating page for id ${node.id} with slug ${node.fields.slug} with initial h1 of ${(node.headings && node.headings[0]) ? node.headings[0].value : "no h1"}`
    )
    createPage({
      path: node.fields.slug,
      component: path.resolve(
        `./src/templates/test-layout.js`
      ),
      context: { id: node.id },
    })
  })

  const yokaiResult = await graphql(`
    query {
        allAirtable {
            edges {
                node {
                    id
                    recordId
                }
            }
        }
    }
  `)

  if (yokaiResult.errors) {
    reporter.panicOnBuild('🚨  ERROR: Loading "yokai" query')
  }


  const yokai = yokaiResult.data.allAirtable.edges
  yokai.forEach(({ node }, index) => {
    console.log(
      `creating page for id ${node.id} with slug /yokai/${node.recordId} `
    )
    console.log(JSON.stringify(node, null, 4))
    createPage({
      path: `/yokai/${node.recordId}`,
      component: path.resolve(
        `./src/templates/yokai-template.js`
      ),
      context: { recordId: node.recordId },
    })
  })

}
```

as you can guess, this is for a specific type of Airtable record, so you'll have to tweak it a bit. It also requires you to have a page-template that you use, referenced in this little chunk:

```
createPage({
      path: `/yokai/${node.recordId}`,
      component: path.resolve(
        `./src/templates/yokai-template.js`
      ),
      context: { recordId: node.recordId },
    })
```

here's what's in our `yokai-template.js` (which appears to need `theme-ui`, which you can add with `npm i theme-ui`)

```
/** @jsx jsx */
import { jsx } from 'theme-ui'
import YokaiFlip from "../components/yokai-flip.js"



export default ({ data }) => {

    return (
    <div
      sx={{
        width: "80%",
        margin: "auto",
        padding: "2em",
      }}
    >
      <div
      sx={{
        width: "100%",
        textAlign: "center"
      }}
      >
        <h1
          sx={{
            fontFamily: "Avenir Next, sans-serif",
            fontWeight: "900",
            fontSize: "4em"
          }}
        >{data.airtable.data.Name}</h1>
      </div>
        <YokaiFlip 
            front={ data.airtable.data.canvaCardFront ? data.airtable.data.canvaCardFront[0].thumbnails.large.url : data.airtable.data.cleanImageJPG ? data.airtable.data.cleanImageJPG[0].thumbnails.full.url : "/_images/gatsby.jpg"} 
            back= { data.airtable.data.canvaCardBack ? data.airtable.data.canvaCardBack[0].thumbnails.large.url : data.airtable.data.cleanImageJPG ? data.airtable.data.cleanImageJPG[0].thumbnails.full.url : "/_images/gatsby.jpg"} 
        />
        <div
            sx={{
                height: "300px"
            }}
        ></div>
        {/* <pre>{JSON.stringify(data, null, 4)}</pre> */}
    </div>
    )
}

export const query = graphql`
query GetRecord($recordId: String!){
    airtable(recordId: { eq: $recordId}) {
        id
        table
        recordId
        data {
            Description
          mainFeature
          Creator
          Link_to_Project
          secondFeature
          Name
          weight
          type
          mainAttack
          region
          specialAttack
          height
          backgroundColor
          foregroundColor
          canvaCardLink
          canvaCardBack {
            id
            thumbnails {
              large {
                url
                width
                height
              }
            }
          }
          canvaCardFront {
            id
            thumbnails {
              large {
                url
                width
                height
              }
            }
          }
          cleanImageJPG {
            thumbnails {
              full {
                url
              }
            }
          }
        }
    }
}`
```




