DEV Community

loading...
Cover image for JAMStack Fun: Combining StackBit, Forestry, Netlify, Gatsby, Hasura, Glitch
Feldroy

JAMStack Fun: Combining StackBit, Forestry, Netlify, Gatsby, Hasura, Glitch

Audrey Roy Greenfeld
Engineer, artist, writer. Executive Director of Margarita Humanitarian Foundation. Co-author of Two Scoops of Django. Creator of FLOSS projects like Cookiecutter. Love @danielfeldroy 💘 and my toddler
・4 min read

For days 6-7 of #100DaysOfCode, I did various JAMStack experiments with SaaS and open-source tools, putting them together to see what would happen.

Trying Out Stackbit

I signed up for a Stackbit account and used their site builder to create a project:

  • Theme: Azimuth
  • Site generator: Gatsby
  • CMS: Forestry (Always wanted to try it!)
  • Deployment: GitHub repository with Netlify build + deploy (the only current options available. I look forward to Gitlab coming soon!)

I connected my Forestry and GitHub accounts.

Stackbit says it deployed my site. Ooh, it's really live:

My deployed Stackbit static site

I clicked Claim to claim the Netlify project. It worked, yay.

Then I clicked Edit in Forestry to edit the content.

Trying Out Forestry

Forestry provides a GUI for editing Gatsby content. It also supports Hugo, Gridsome, Jekyll, and other static site generators.

It's pretty cool, and I could see it being useful for people who can't build their static site locally or are editing from a mobile device.

The lag between updating a site via Forestry and seeing the new deployed version on Netlify was a few minutes. For my purposes, I find running npm run develop easier because I can see the static site changes on localhost in seconds.

Adding a Netlify Function

Next I added a Netlify function. Initially it'll do almost nothing, but I could see it implementing something dynamic and server-side like what you would expect of an Express or Django web application.

I cloned the GitHub repo, then created a Netlify function by copying functions/hello.js by @kentcdodds into my project. I added it to my build in netlify.toml. Then I git committed and then went to Netlify to watch the build go.

Now that the function's deployed, it's here:
https://curious-rosemary-e8299.netlify.app/.netlify/functions/hello?name=Uma

Whatever you pass into name gets shown on the page by the function:

// functions/hello.js from https://kentcdodds.com/blog/super-simple-start-to-serverless
exports.handler = async event => {
    const subject = event.queryStringParameters.name || 'World'
    return {
      statusCode: 200,
      body: `Hello ${subject}!`,
    }
  }
Enter fullscreen mode Exit fullscreen mode

I'd like to expand this into something real and maybe have it get triggered by a form submission via a Netlify form like the contactForm provided by the sample code. But in the interest of time, I'm saving that for another day to focus on getting the Gatsby site to display dynamic remote API data.

Experimenting with Gatsby

It's been years since I last used React, so getting Gatsby to do what I wanted was a challenge. My hope at this point was to replicate what a Django ListView does in JAMstack.

I created an items.js page to play in:

import React from "react"
export default ({ data }) => (
    <div>
        Hello!
    </div>
)
Enter fullscreen mode Exit fullscreen mode

Next, I looked into populating the page with dynamic data. If I could grab data onto this static page from a remote GraphQL endpoint, that would be great.

Gatsby uses GraphQL, so I started with using that as test data:

import React from "react"
export default ({ data }) => (
    <div>
        <h1>Items List {data.site.siteMetadata.title}</h1>
        <p>This is a static site, but it's loading items dynamically from GraphQL:</p>
        <ul>
          {data.site.siteMetadata.header.nav_links.map(x=> <li>{x.label}</li>)}
        </ul>
    </div>
)

export const query = graphql`
  query {
    site {
      siteMetadata {
        header {
          nav_links {
            label
          }
        }
      }
    }
  }
`
Enter fullscreen mode Exit fullscreen mode

Setting Up a GraphQL API with Hasura

Hasura is an open-source, Heroku-deployable tool that can take existing databases and give you a GraphQL API.

I did the first part of the Hasura tutorial and loved it. Now I have a todos table I can query:

query MyQuery {
  todos {
    id
    title
  }
}

Enter fullscreen mode Exit fullscreen mode

The response from Hasura with my sample data:

{
  "data": {
    "todos": [
      {
        "id": 1,
        "title": "My First Todo"
      },
      {
        "id": 2,
        "title": "Second Todo"
      }
    ]
  }
}
Enter fullscreen mode Exit fullscreen mode

Adding a New Gatsby GraphQL Root

I did an npm install gatsby-source-graphql then added my Hasura GraphQL API to gatsby-config.js:

I see that the example from the Gatsby docs points at https://api.graphcms.com/simple/v1/swapi which is down.

Looks like that site, GraphCMS, was featured on ProductHunt today...I'll sign up and see if they have an updated sample endpoint. Hmm, it looks like an interesting rabbit hole for another day.

In Hasura, I went to Remote Schemas > *Try it with Glitch* and found hasura-sample-remote-schema.glitch.me/

With @danielfeldroy 's help we added the new root to gatsby-config.js:

        {
            resolve: "gatsby-source-graphql",
            options: {
              // This type will contain remote schema Query type
              typeName: "query",
              // This is the field under which it's accessible
              fieldName: "hasuraSample",
              // URL to query from
              url: "https://hasura-sample-remote-schema.glitch.me/",
            },
          },
Enter fullscreen mode Exit fullscreen mode

Then he figured out this query worked in Glitch:

query {
  hello 
}
Enter fullscreen mode Exit fullscreen mode

In http://127.0.0.1:8000/___graphql we got this query to work:

query {hasuraSample {
  hello
}}
Enter fullscreen mode Exit fullscreen mode

Showing Remote GraphQL Data on a Gatsby Page

Finally, I updated items.js to be:

import React from "react"
export default ({ data }) => (
    <div>
        <h1>Items List</h1>
        <p>This is a static site, but it's loading items dynamically from GraphQL:</p>
        <ul>
          {data.hasuraSample.hello}
        </ul>
    </div>
)

export const query = graphql`
  query {hasuraSample {
    hello
  }}
`
Enter fullscreen mode Exit fullscreen mode

With that, http://localhost:8000/items now shows a static Gatsby page with the live data from the Glitch-hosted Hasura Sample Remote Schema!

JAMstack: Putting It All Together

It was really fun to play around and put all these JAMstack toys together, particularly the ones that auto-configured themselves and auto-deployed. Every piece served a purpose and did it well. That was cool!

Discussion (3)

Collapse
delaudio profile image
delaudio

Thank you for your overview 😃
Definitely need to try Hasura!

I'm a super fan of Forestry and I suggest you to try the instant preview feature forestry.io/docs/previews/instant-...

So no need to wait or to run develop on localhost if you just want to add or edit some content 🤩

Collapse
audreyfeldroy profile image
Audrey Roy Greenfeld Author

Cool, thanks for the tip! I'm going to try out Forestry's instant preview now!

Collapse
astagi profile image
Andrea Stagi

Great article, thank you Audrey! I recently discovered Netlify and wrote an article about CI/CD using it (dev.to/astagi/continuous-integrati...), I didn't know Forestry and Hasura, look great! I'll give them a try!