I've always wanted to have an old school guestbook for my site. I finally built one using Netlify Functions and Github Gist.
Back in the 90's, it was common for websites to have guest books for visitors to sign. With the exponential growth of the internet in the 2000's, these "Guest Books" gave way to social media, and you hardly ever see them anymore.
The other day I started to wonder, how hard would it be to implement on these days with modern technology. Back then, running a guest book involved setting up a database and back end, but these days there are tools like Fauna and Gist that lets you store data without database and takes minimal effort to setup.
My biggest hurdle when setting up my guest book is figuring out where to put the data. I decided the best place would be in a Gist, when a user submitted their message, a serverless function would pick it up, call Github to get the current gist, append the users message to the end, and send it back up to Github.
One of the reasons guest books died on the internet was it was easy to get hacked, so one of my biggest considerations was how to secure this thing. Luckily this turned out to be pretty straightforward. First off since the data was stored in a gist, I didn't have to worry about my backend getting hacked and worst case scenario, I could just wipe the gist.
However I still wanted to sanitize the input so I used DOMPurify to sanitize any
user input prior to submission, my guest book accepts any text however if you
try adding a
<script src="verybadscript.js"></script>, the site will strip
that away before sending up the data.
The last security related hurdle was how was I going to allow users to add to the guest book anonymously. The Github API allows you to read gists without authentication; however, you must be authenticated to update it. To get around this I moved the update logic into a serverless function, this way I could furnish an access token to the API call without exposing any secrets to the client.
The User Interface was probably the easiest part, but still required some thought. I had two pieces of state that I had to keep up with: user submission state, and guest book loading state.
I settled on two pieces of state:
The first piece of state track the user submission, and functions like a state
machine with either "pre", "submitting" or "post" states. The second piece of
state tracks the loading of the guest book gist. There is one last piece of
state that is crucial:
Whenever you sign the guest book, you want to see your submission. The issue I
ran into is after submitting your message, there was no way to inform the
guest book to reload it's data. To solve this i used
along with a
useEffect hook that would re-fetch the data anytime the flag was
flipped to true.
I'm not quite done tweaking the guest book. Some improvements:
You can sign my guest book here
Wouldn't it be nice to have your NetlifyCMS configuration in JS rather than YAML? Here's how you can do that.
Instead of rebuilding my website this year, I migrated it from Gatsby to NextJS. Here's how that went.
How to setup Storybook to work nicely with Styled Components custom theme.
There are tons of libraries out there that will help you with icons in React, but there's an even easier way.
A list of 10 awesome UI libraries that will help you bootstrap your next React project