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:
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}!`,
}
}
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>
)
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
}
}
}
}
}
`
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
}
}
The response from Hasura with my sample data:
{
"data": {
"todos": [
{
"id": 1,
"title": "My First Todo"
},
{
"id": 2,
"title": "Second Todo"
}
]
}
}
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/",
},
},
Then he figured out this query worked in Glitch:
query {
hello
}
In http://127.0.0.1:8000/___graphql we got this query to work:
query {hasuraSample {
hello
}}
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
}}
`
With that, http://localhost:8000/items now shows a static Gatsby page with the live data from the Glitch-hosted Hasura Sample Remote Schema!
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!
Top comments (3)
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 🤩
Cool, thanks for the tip! I'm going to try out Forestry's instant preview now!
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!