If you haven’t used Gatsby before have a read about why it’s fast in every way that matters, and if you haven’t used FaunaDB before you’re in for a treat. If you’re looking to make your static sites full blown Jamstack applications this is the back end solution for you!
This tutorial will only focus on the operations you need to use FaunaDB to power a comment system for a Gatsby blog. The app comes complete with inputs fields that allow users to comment on your posts and an admin area for you to approve or delete comments before they appear on each post. Authentication is provided by Netlify’s Identity widget and it’s all sewn together using Netlify serverless functions and an Apollo/GraphQL API that pushes data up to a FaunaDB database collection.
I chose FaunaDB for the database for a number of reasons. Firstly there’s a very generous free tier! perfect for those small projects that need a back end, there’s native support for GraphQL queries and it has some really powerful indexing features!
…and to quote the creators;
No matter which stack you use, or where you’re deploying your app, FaunaDB gives you effortless, low-latency and reliable access to your data via APIs familiar to you
You’ll come back to these later but in case you’re wondering
GATSBY_FAUNA_DB is the FaunaDB secret key for your database
GATSBY_FAUNA_COLLECTION is the FaunaDB collection name
GATSBY_SHOW_SIGN_UP is used to hide the Sign up button when the site is in production
GATSBY_ADMIN_ID is a user id that Netlify Identity will generate for you
If you’re the curious type you can get a taster of the app by running gatsby develop or yarn develop and then navigate to http://localhost:8000 in your browser.
FaunaDB
So Let’s get cracking, but before we write any operations head over to https://fauna.com/ and sign up!
Database and Collection
Create a new database by clicking NEW DATABASE
Name the database: I’ve called the demo database fauna-gatsby-comments
Create a new Collection by clicking NEW COLLECTION
Name the collection: I’ve called the demo collection demo-blog-comments
Server Key
Now you’ll need to to set up a server key. Go to SECURITY
Create a new key by clicking NEW KEY
Select the database you want the key to apply to, fauna-gatsby-comments for example
Set the Role as Admin
Name the server key: I’ve called the demo key demo-blog-server-key
Environment Variables Pt. 1
Copy the server key and add it to GATSBY_FAUNA_DB in .env.development, .env.production and .env.
You’ll also need to add the name of the collection to GATSBY_FAUNA_COLLECTION in .env.development, .env.production and .env.
Adding these values to .env are just so you can test your development FaunaDB operations, which you’ll do next.
Let’s start by creating a comment so head back to boop.js:
Create is the FaunaDB method to create an entry within a collection
Collection is area in the database to store the data. It takes the name of the collection as the first argument and a data object as the second.
The second argument is the shape of the data you need to drive the applications comment system.
For now you’re going to hard-code slug, name and comment but in the final app these values are captured by the input form on the posts page and passed in via args
The breakdown for the shape is as follows;
isApproved is the status of the comment and by default it’s false until we approve it in the Admin page
slug is the path to the post where the comment was written
date is the time stamp the comment was written
name is the name the user entered in the comments from
comment is the comment the user entered in the comments form
When you (or a user) creates a comment you’re not really interested in dealing with the response because as far as the user is concerned all they’ll see is either a success or error message.
After a user has posted a comment it will go in to your Admin queue until you approve it but if you did want to return something you could surface this in the UI by returning something from the createComment function.
Create a comment
If you’ve hard coded a slug, name and comment you can now run the following in your CLI
node boop createComment
If everything worked correctly you should see a log in your terminal of the new comment.
If you head over to COLLECTIONS in FaunaDB you should see your new entry in the collection.
You’ll need to create a few more comments while in development so change the hard-coded values for name and comment and run the following again.
node boop createComment
Do this a few times so you end up with at least three new comments stored in the database, you’ll use these in a moment.
Delete comment by id
Now that you can create comments you’ll also need to be able to delete a comment.
By adding the commentId of one of the comments you created above you can delete it from the database. The commentId is the id in the ref.@ref object
Again you’re not really concerned with the return value here but if you wanted to surface this in the UI you could do so by returning something from the deleteCommentById function.
Delete is the FaunaDB delete method to delete entries from a collection
Ref is the unique FaunaDB ref used to identify the entry
Collection is area in the database where the data is stored
If you’ve hard coded a commentId you can now run the following in your CLI:
node boop deleteCommentById
If you head back over to COLLECTIONS in FaunaDB you should see that entry no longer exists in collection
Indexes
Next you’re going to create an INDEX in FaunaDB.
An INDEX allows you to query the database with a specific term and define a specific data shape to return.
When working with GraphQL and / or TypeScript this is really powerful because you can use FaunaDB indexes to return only the data you need and in a predictable shape. This makes data typing responses in GraphQL and / TypeScript a dream… I’ve worked on a number of applications that just return a massive object of useless values which will inevitably cause bugs in your app. blurg!
Go to INDEXES and click NEW INDEX
Name the index: I’ve called this one get-all-comments
Set the source collection to the name of the collection you setup earlier
As mentioned above when you query the database using this index you can tell FaunaDB which parts of the entry you want to return.
You can do this by adding “values” but be careful to enter the values exactly as they appear below because (on the FaunaDB free tier) you can’t amend these after you’ve created them so if there’s a mistake you’ll have to delete the index and start again… bummer!
The values you need to add are as follows:
ref
data.isApproved
data.slug
data.date
data.name
data.comment
After you’ve added all the values you can click SAVE.
The shape of the returned result here is an array of the same shape you defined in the Index “values”
If you run the following you should see the list of all the comments you created earlier:
node boop getAllComments
Get comments by slug
You’re going to take a similar approach as above but this time create a new Index that allows you to query FaunaDB in a different way. The key difference here is that when you get-comments-by-slug you’ll need to tell FaunaDB about this specific term and you can do this by adding data.slug to the Terms field.
Go to INDEX and click NEW INDEX
Name the index, I’ve called this one get-comments-by-slug
Set the source collection to the name of the collection you setup earlier
Add data.slug in the terms field
The values you need to add are as follows:
ref
data.isApproved
data.slug
data.date
data.name
data.comment
After you’ve added all the values you can click SAVE.
The shape of the returned result here is an array of the same shape you defined in the Index “values” you can create this shape in the same way you did above and be sure to add a value for terms. Again be careful to enter these with care.
If you run the following you should see the list of all the comments you created earlier but for a specific slug:
node boop getCommentsBySlug
Approve comment by id
When you create a comment you manually set the isApproved value to false. This prevents the comment from being shown in the app until you approve it.
You’ll now need to create a function to do this but you’ll need to hard-code a commentId. Use a commentId from one of the comments you created earlier:
Ref is the unique FaunaDB ref used to identify the entry
Collection is area in the database where the data is stored
If you’ve hard coded a commentId you can now run the following in your CLI:
node boop approveCommentById
If you run the getCommentsBySlug again you should now see the isApproved status of the entry you hard-coded the commentId for will have changed to true.
node boop getCommentsBySlug
These are all the operations required to manage the data from the app.
In the repo if you have a look at apollo-graphql.js which can be found in functions/apollo-graphql you’ll see the all of the above operations. As mentioned before the hard-coded values are replaced by args, these are the values passed in from various parts of the app.
Netlify
Assuming you’ve completed the Netlify sign up process or already have an account with Netlify you can now push the demo app to your GitHub account.
To do this you’ll need to have initialize git locally, added a remote and have pushed the demo repo upstream before proceeding.
If you click the “New site from Git” button on the Netlify dashboard you can authorize access to your GitHub account and select the gatsby-fauna-comments repo to enable Netlify’s Continuous Deployment. You’ll need to have deployed at least once so that we have a pubic URL of your app.
The URL will look something like this https://ecstatic-lewin-b1bd17.netlify.app but feel free to rename it and make a note of the URL as you’ll need it for the Netlify Identity step mentioned shortly.
Environment Variables Pt. 2
In a previous step you added the FaunaDB database secret key and collection name to your .env files(s). You’ll also need to add the same to Netlify’s Environment variables.
Navigate to Settings from the Netlify navigation
Click on Build and deploy
Either select Environment or scroll down until you see Environment variables
Click on Edit variables
Proceed to add the following:
GATSBY_SHOW_SIGN_UP = false GATSBY_FAUNA_DB = you FaunaDB secret key GATSBY_FAUNA_COLLECTION = you FaunaDB collection name
While you’re here you’ll also need to amend the Sensitive variable policy, select Deploy without restrictions
Netlify Identity Widget
I mentioned before that when a comment is created the isApproved value is set to false, this prevents comments from appearing on blog posts until you (the admin) have approved them. In order to become admin you’ll need to create an identity.
If you’ve completed the Continuous Deployment step above you can navigate to the Identity page from the Netlify navigation.
You wont see any users in here just yet so lets use the app to connect the dots, but before you do that make sure you click Enable Identity
Before you continue I just want to point out you’ll be using netlify dev instead of gatsby develop or yarn develop from now on. This is because you’ll be using some “special” Netlify methods in the app and staring the server using netlify dev is required to spin up various processes you’ll be using.
Spin up the app using netlify dev
Navigate to http://localhost:8888/admin/
Click the Sign Up button in the header
You will also need to point the Netlify Identity widget at your newly deployed app URL. This was the URL I mentioned you’ll need to make a note of earlier, if you’ve not renamed your app it’ll look something like this https://ecstatic-lewin-b1bd17.netlify.app/ There will be a prompt in the pop up window to Set site’s URL.
You can now complete the necessary sign up steps.
After sign up you’ll get an email asking you to confirm you identity and once that’s completed refresh the Identity page in Netlify and you should see yourself as a user.
It’s now login time, but before you do this find Identity.js in src/components and temporarily un-comment the console.log() on line 14. This will log the Netlify Identity user object to the console.
Restart your local server
Spin up the app again using netlify dev
Click the Login button in the header
If this all works you should be able to see a console log for netlifyIdentity.currentUser: find the id key and copy the value.
Set this as the value for GATSBY_ADMIN_ID = in both .env.production and .env.development
You can now safely remove the console.log() on line 14 in Identity.js or just comment it out again.
GATSBY_ADMIN_ID = your Netlify Identity user id
…and finally
Restart your local server
Spin up the app again using netlify dev
Now you should be able to login as “Admin”… hooray!
Navigate to http://localhost:8888/admin/ and Login.
It’s important to note here you’ll be using localhost:8888 for development now and NOT localhost:8000 which is more common with Gatsby development
Before you test this in the deployed environment make sure you go back to Netlify’s Environment variables and add your Netlify Identity user id to the Environment variables!
Navigate to Settings from the Netlify navigation
Click on Build and deploy
Either select Environment or scroll down until you see Environment variables
Click on Edit variables
Proceed to add the following:
GATSBY_ADMIN_ID = your Netlify Identity user id
If you have a play around with the app and enter a few comments on each of the posts then navigate back to Admin page you can choose to either approve or delete the comments.
Naturally only approved comments will be displayed on any given post and deleted ones are gone forever.
If you’ve used this tutorial for your project I’d love to hear from you at @pauliescanlon.
By Paulie Scanlon (@pauliescanlon), Front End React UI Developer / UX Engineer: After all is said and done, structure + order = fun.
Roll Your Own Comments With Gatsby and FaunaDB
If you haven’t used Gatsby before have a read about why it’s fast in every way that matters, and if you haven’t used FaunaDB before you’re in for a treat. If you’re looking to make your static sites full blown Jamstack applications this is the back end solution for you!
This tutorial will only focus on the operations you need to use FaunaDB to power a comment system for a Gatsby blog. The app comes complete with inputs fields that allow users to comment on your posts and an admin area for you to approve or delete comments before they appear on each post. Authentication is provided by Netlify’s Identity widget and it’s all sewn together using Netlify serverless functions and an Apollo/GraphQL API that pushes data up to a FaunaDB database collection.
I chose FaunaDB for the database for a number of reasons. Firstly there’s a very generous free tier! perfect for those small projects that need a back end, there’s native support for GraphQL queries and it has some really powerful indexing features!
…and to quote the creators;
You can see the finished comments app here.
Get Started
To get started clone the repo at https://github.com/PaulieScanlon/fauna-gatsby-comments
or:
Then install all the dependencies:
Also
cd
in tofunctions/apollo-graphql
and install the dependencies for the Netlify function:This is a separate package and has its own dependencies, you’ll be using this later.
We also need to install the Netlify CLI as you’ll also use this later:
Now lets add three new files that aren’t part of the repo.
At the root of your project create a
.env
.env.development
and.env.production
Add the following to
.env
:Add the following to
.env.development
:Add the following to
.env.production
:You’ll come back to these later but in case you’re wondering
GATSBY_FAUNA_DB
is the FaunaDB secret key for your databaseGATSBY_FAUNA_COLLECTION
is the FaunaDB collection nameGATSBY_SHOW_SIGN_UP
is used to hide the Sign up button when the site is in productionGATSBY_ADMIN_ID
is a user id that Netlify Identity will generate for youIf you’re the curious type you can get a taster of the app by running
gatsby develop
oryarn develop
and then navigate tohttp://localhost:8000
in your browser.FaunaDB
So Let’s get cracking, but before we write any operations head over to https://fauna.com/ and sign up!
Database and Collection
fauna-gatsby-comments
demo-blog-comments
Server Key
Now you’ll need to to set up a server key. Go to SECURITY
fauna-gatsby-comments
for exampledemo-blog-server-key
Environment Variables Pt. 1
Copy the server key and add it to
GATSBY_FAUNA_DB
in.env.development
,.env.production
and.env
.You’ll also need to add the name of the collection to
GATSBY_FAUNA_COLLECTION
in.env.development
,.env.production
and.env
.Adding these values to
.env
are just so you can test your development FaunaDB operations, which you’ll do next.Let’s start by creating a comment so head back to
boop.js
:The breakdown of this function is as follows;
q
is the instance offaunadb.query
Create
is the FaunaDB method to create an entry within a collectionCollection
is area in the database to store the data. It takes the name of the collection as the first argument and a data object as the second.The second argument is the shape of the data you need to drive the applications comment system.
For now you’re going to hard-code
slug
,name
andcomment
but in the final app these values are captured by the input form on the posts page and passed in via argsThe breakdown for the shape is as follows;
isApproved
is the status of the comment and by default it’s false until we approve it in the Admin pageslug
is the path to the post where the comment was writtendate
is the time stamp the comment was writtenname
is the name the user entered in the comments fromcomment
is the comment the user entered in the comments formWhen you (or a user) creates a comment you’re not really interested in dealing with the response because as far as the user is concerned all they’ll see is either a success or error message.
After a user has posted a comment it will go in to your Admin queue until you approve it but if you did want to return something you could surface this in the UI by returning something from the
createComment
function.Create a comment
If you’ve hard coded a
slug
,name
andcomment
you can now run the following in your CLIIf everything worked correctly you should see a log in your terminal of the new comment.
If you head over to COLLECTIONS in FaunaDB you should see your new entry in the collection.
You’ll need to create a few more comments while in development so change the hard-coded values for
name
andcomment
and run the following again.Do this a few times so you end up with at least three new comments stored in the database, you’ll use these in a moment.
Delete comment by id
Now that you can create comments you’ll also need to be able to delete a comment.
By adding the
commentId
of one of the comments you created above you can delete it from the database. ThecommentId
is theid
in theref.@ref
objectAgain you’re not really concerned with the return value here but if you wanted to surface this in the UI you could do so by returning something from the
deleteCommentById
function.The breakdown of this function is as follows
client
is the FaunaDB client instancequery
is a method to get data from FaunaDBq
is the instance offaunadb.query
Delete
is the FaunaDB delete method to delete entries from a collectionRef
is the unique FaunaDB ref used to identify the entryCollection
is area in the database where the data is storedIf you’ve hard coded a
commentId
you can now run the following in your CLI:If you head back over to COLLECTIONS in FaunaDB you should see that entry no longer exists in collection
Indexes
Next you’re going to create an INDEX in FaunaDB.
An INDEX allows you to query the database with a specific term and define a specific data shape to return.
When working with GraphQL and / or TypeScript this is really powerful because you can use FaunaDB indexes to return only the data you need and in a predictable shape. This makes data typing responses in GraphQL and / TypeScript a dream… I’ve worked on a number of applications that just return a massive object of useless values which will inevitably cause bugs in your app. blurg!
get-all-comments
As mentioned above when you query the database using this index you can tell FaunaDB which parts of the entry you want to return.
You can do this by adding “values” but be careful to enter the values exactly as they appear below because (on the FaunaDB free tier) you can’t amend these after you’ve created them so if there’s a mistake you’ll have to delete the index and start again… bummer!
The values you need to add are as follows:
ref
data.isApproved
data.slug
data.date
data.name
data.comment
After you’ve added all the values you can click SAVE.
Get all comments
The breakdown of this function is as follows
client
is the FaunaDB client instancequery
is a method to get data from FaunaDBq
is the instance offaunadb.query
Paginate
paginates the responsesMatch
returns matched resultsIndex
is the name of the Index you just createdThe shape of the returned result here is an array of the same shape you defined in the Index “values”
If you run the following you should see the list of all the comments you created earlier:
Get comments by slug
You’re going to take a similar approach as above but this time create a new Index that allows you to query FaunaDB in a different way. The key difference here is that when you
get-comments-by-slug
you’ll need to tell FaunaDB about this specific term and you can do this by addingdata.slug
to the Terms field.get-comments-by-slug
data.slug
in the terms fieldThe values you need to add are as follows:
ref
data.isApproved
data.slug
data.date
data.name
data.comment
After you’ve added all the values you can click SAVE.
The breakdown of this function is as follows:
client
is the FaunaDB client instancequery
is a method to get data from FaunaDBq
is the instance offaunadb.query
Paginate
paginates the responsesMatch
returns matched resultsIndex
is the name of the Index you just createdThe shape of the returned result here is an array of the same shape you defined in the Index “values” you can create this shape in the same way you did above and be sure to add a value for terms. Again be careful to enter these with care.
If you run the following you should see the list of all the comments you created earlier but for a specific
slug
:Approve comment by id
When you create a comment you manually set the
isApproved
value to false. This prevents the comment from being shown in the app until you approve it.You’ll now need to create a function to do this but you’ll need to hard-code a
commentId
. Use acommentId
from one of the comments you created earlier:The breakdown of this function is as follows:
client
is the FaunaDB client instancequery
is a method to get data from FaunaDBq
is the instance offaunadb.query
Update
is the FaundaDB method up update an entryRef
is the unique FaunaDB ref used to identify the entryCollection
is area in the database where the data is storedIf you’ve hard coded a
commentId
you can now run the following in your CLI:If you run the
getCommentsBySlug
again you should now see theisApproved
status of the entry you hard-coded thecommentId
for will have changed totrue
.These are all the operations required to manage the data from the app.
In the repo if you have a look at
apollo-graphql.js
which can be found infunctions/apollo-graphql
you’ll see the all of the above operations. As mentioned before the hard-coded values are replaced byargs
, these are the values passed in from various parts of the app.Netlify
Assuming you’ve completed the Netlify sign up process or already have an account with Netlify you can now push the demo app to your GitHub account.
To do this you’ll need to have initialize git locally, added a remote and have pushed the demo repo upstream before proceeding.
You should now be able to link the repo up to Netlify’s Continuous Deployment.
If you click the “New site from Git” button on the Netlify dashboard you can authorize access to your GitHub account and select the
gatsby-fauna-comments
repo to enable Netlify’s Continuous Deployment. You’ll need to have deployed at least once so that we have a pubic URL of your app.The URL will look something like this
https://ecstatic-lewin-b1bd17.netlify.app
but feel free to rename it and make a note of the URL as you’ll need it for the Netlify Identity step mentioned shortly.Environment Variables Pt. 2
In a previous step you added the FaunaDB database secret key and collection name to your
.env
files(s). You’ll also need to add the same to Netlify’s Environment variables.Proceed to add the following:
While you’re here you’ll also need to amend the Sensitive variable policy, select Deploy without restrictions
Netlify Identity Widget
I mentioned before that when a comment is created the
isApproved
value is set tofalse
, this prevents comments from appearing on blog posts until you (the admin) have approved them. In order to become admin you’ll need to create an identity.You can achieve this by using the Netlify Identity Widget.
If you’ve completed the Continuous Deployment step above you can navigate to the Identity page from the Netlify navigation.
You wont see any users in here just yet so lets use the app to connect the dots, but before you do that make sure you click Enable Identity
Before you continue I just want to point out you’ll be using
netlify dev
instead ofgatsby develop
oryarn develop
from now on. This is because you’ll be using some “special” Netlify methods in the app and staring the server usingnetlify dev
is required to spin up various processes you’ll be using.netlify dev
http://localhost:8888/admin/
You will also need to point the Netlify Identity widget at your newly deployed app URL. This was the URL I mentioned you’ll need to make a note of earlier, if you’ve not renamed your app it’ll look something like this
https://ecstatic-lewin-b1bd17.netlify.app/
There will be a prompt in the pop up window to Set site’s URL.You can now complete the necessary sign up steps.
After sign up you’ll get an email asking you to confirm you identity and once that’s completed refresh the Identity page in Netlify and you should see yourself as a user.
It’s now login time, but before you do this find
Identity.js
insrc/components
and temporarily un-comment theconsole.log()
on line 14. This will log the Netlify Identity user object to the console.netlify dev
If this all works you should be able to see a console log for
netlifyIdentity.currentUser:
find theid
key and copy the value.Set this as the value for
GATSBY_ADMIN_ID =
in both.env.production
and.env.development
You can now safely remove the
console.log()
on line 14 inIdentity.js
or just comment it out again.…and finally
netlify dev
Now you should be able to login as “Admin”… hooray!
Navigate to
http://localhost:8888/admin/
and Login.It’s important to note here you’ll be using
localhost:8888
for development now and NOTlocalhost:8000
which is more common with Gatsby developmentBefore you test this in the deployed environment make sure you go back to Netlify’s Environment variables and add your Netlify Identity user
id
to the Environment variables!Proceed to add the following:
If you have a play around with the app and enter a few comments on each of the posts then navigate back to Admin page you can choose to either approve or delete the comments.
Naturally only approved comments will be displayed on any given post and deleted ones are gone forever.
If you’ve used this tutorial for your project I’d love to hear from you at @pauliescanlon.
By Paulie Scanlon (@pauliescanlon), Front End React UI Developer / UX Engineer: After all is said and done, structure + order = fun.
Visit Paulie’s Blog at: www.paulie.dev
The post Roll Your Own Comments With Gatsby and FaunaDB appeared first on CSS-Tricks.
CSS-Tricks