A service for adding basic comment functionality to any blog post/webpage. Visitors to your site can leave comments and view others' comments.
- Built with nbb
- Deployed on AWS Lambda using Serverless Framework
- Uses DynamoDB for storage
You can:
- Deploy it to your own AWS account to use it on your own site
- Run it locally to poke around and see how it works
- See it in action (scroll to the bottom of the linked page)
I wanted to allow people visiting my personal blog to be able to leave comments without creating any sort of account/login. I used Google reCAPTCHA v3 to prevent bot abuse.
nbb-comments
uses an AWS Lambda function (backed by DynamoDB) to serve HTTP requests to:
- add a new comment for a certain blog post
- list existing comments for a certain blog post
- retrieve the HTML to render the comments form
It uses htmx to handle interactions with the server and make dynamic updates to the DOM without reloading the page.
Once you deploy your backend, adding it to any webpage is as simple as:
<!-- add this to <head> -->
<script src="https://unpkg.com/htmx.org@1.8.0" async></script>
<!-- add this somewhere in your <body> -->
<h2>Leave a comment</h2>
<form id="comment-form" hx-get="https://<your-deployed-lambda-url>/comments-form?post-id=example-post-id" hx-trigger="load"></form>
<h2>Comments</h2>
<div id="comments-list" hx-get="https://<your-deployed-lambda-url>/comments?post-id=example-post-id" hx-swap"innerHTML" hx-trigger="load"></div>
First, install node dependencies:
npm install
Then, to run the server locally, run:
bb dev-server
Then visit http://localhost:3000
and you can see it in action!
To use this for your own blog/site, you will need to:
- Setup your AWS credentials so that you can deploy using Serverless Framework
- Register a Google reCAPTCHA v3 key
- Install node/npm
-
Create an
.env
with the following contents:RECAPTCHA_SECRET="<your-recaptcha-secret-here>" RECAPTCHA_SITEKEY="<your-recaptcha-sitekey-here>" ALLOWED_ORIGIN_URL="<your-frontend-url>" # for example "https://nickcellino.com"
-
Run
npm install
in the root of this project. -
Run
npx serverless deploy
. If everything worked correctly, this should print out something like:➜ npx serverless deploy Deploying comments-api to stage dev (us-east-1) ✔ Service deployed to stack comments-api-dev (84s) endpoint: ANY - https://s390h072qf.execute-api.us-east-1.amazonaws.com/{proxy+} functions: comments-api: comments-api-dev-comments-api (65 MB) Monitor all your API routes with Serverless Console: run "serverless --console"
Take note of the endpoint url you get back. In this example, it is https://s390h072qf.execute-api.us-east-1.amazonaws.com
If you can see that, your backend is all set!
-
Load
htmx
script somewhere in the<head>
of your HTML like so:<head> ... <script src="https://unpkg.com/htmx.org@1.8.0" async></script> ... </head>
This is used to dynamically fetch the comments form and comments from the backend.
-
Add the comments form somewhere on your page like so (replacing your-backend-url with the proper value for your backend):
<form id="comment-form" hx-get="<your-backend-url>/comments-form?post-id=example-post-id" hx-trigger="load"> </form>
For this step and the next, you should specify a value for the post-id query parameter that is specific to whatever page you are adding this functionality to. If you add this to a different page, you would use a different post-id in order to have a separate comment thread per-page.
-
Add the comments list (where the comemnts will actually be displayed) somewhere on your page like so (replacing your-backend-url with the proper value for your backend):
<div id="comments-list" hx-get="<your-backend-url>/comments?post-id=example-post-id" hx-swap"innerHTML" hx-trigger="load"> </div>
Once you have done that, you are all set to receive brilliant insights from random strangers on the internet!
You can find a minimal working example of this here.
The HTML snippets above will load HTML from the server and render it onto the page. You will need to know what that rendered HTML looks like in order to style it.
You can also run the dev server to play around with the styling.
<form
id="comment-form"
hx-post="http://localhost:3000/comments"
hx-swap="afterbegin"
hx-target="#comments-list"
hx-trigger="submit"
hx-swap-oob="true">
<input type="hidden" name="post-id" value="example-post-id">
<label for="author">Name (optional)</label>
<input type="text" name="author" id="author-input" hx-swap-oob="true">
<label for="message">Comment</label>
<textarea name="message" required="true" rows="5" id="message-input" hx-swap-oob="true"></textarea>
<script>
function announce(token) {
const event = new Event('recaptcha-verified');
const elem = document.querySelector('#comment-form');
elem.dispatchEvent(event);
}
</script>
<script src="https://www.google.com/recaptcha/api.js"></script>
<button type="submit">Submit</button>
</form>
<div
id="comments-list"
hx-get="http://localhost:3000/comments?post-id=example-post-id"
hx-swap="innerhtml"
hx-trigger="load">
<div class="comment">
<p class="name">
<strong>Anonymous</strong> said...
</p>
<p class="message">Hi there</p>
<p class="datetime">20:22, September 2, 2022</p>
</div>
<div class="comment">
<p class="name">
<strong>Nick</strong> said...
</p>
<p class="message">Great post, Nick!</p>
<p class="datetime">20:21, September 2, 2022</p>
</div>
</div>
There is a very, very basic example of styling in the example HTML.
<style>
.comment {
border-bottom: 1px solid;
}
input, textarea {
width: 100%;
margin-bottom: 5px;
}
button {
margin-top: 5px;
}
</style>
That will result in this magnificence: