Adding Comments to My Website
I have had comments in my website for some time, this post is about how I did it and the improvements I made for better UX.
- Published on .
- Last updated on .
Note: I stopped accepting comments in favour of webmentions, this post is here for archiving purposes.
My website is written in Rust
with Rocket
framework. But, just like any other website, what language or framework I use doesn't matter here. The source code can be found at my codeberg repository.
Using SQLite for database
This was a hard one to choose, I have many things planned for this website, most of which would require a high performing database. But I ended up using SQLite
as it is easy to maintain and work on. Taking backups is done by a simple rsync
command!
I created a table named comments
and I set all columns as text, including the ID as I will be using UUID (Universally Unique IDentifier) for it. The SQL looked something like this:
CREATE TABLE IF NOT EXISTS comments (
id TEXT NOT NULL, -- random UUID
post TEXT NOT NULL, -- URL for the page
name TEXT NOT NULL, -- Optional name, defaulted to anonymous
email TEXT, -- optional email
website TEXT, -- optional website for the commenter
comment TEXT NOT NULL, -- the comment
commenter TEXT NOT NULL, -- random UUID
reply_to TEXT -- something for the future threaded replies
)
You might have noticed that I did not tell SQLite to set the default value for the name
field with name TEXT DEFAULT 'anonymous'
. This is because of a bug I faced in the rust SQLite library I am using, the library was not converting Option::None
as NULL
in SQLite. So instead, I am programmatically setting the default value for now.
The comments are sent as a post request, I do some request guards there to avoid spam, more on that in the next section.
Spam control
One of the major concerns I have had about implementing a comment system was the spam control. I believe that I have very low traffic for this website as I don't have analytics to confirm, and I delete access logs fairly frequently.
I initially just accepted all the comments. Well, you could probably guess what happened, a low traffic website means that there are more bots crawling my site than humans visiting it. I frequently received spam messages, most containing links to some pharmacy in India, and some were just trolls. The links were easy to handle, I just show plain text in comments, so none of the links were rendered as HTML to avoid the visitors and search engines navigating to it.
My first plan for moderation was to send a push notification to my android phone whenever a comment was added to the website so that I can delete it quickly. I wanted to do it using UnifiedPush as I already have NextPush server hosted in my Nextcloud instance. Don't think that it is too much work, if you have a notification server set-up, it is just a matter of sending a POST
request like I did. If you do not have a server to set one up, something like ntfy.sh might interest you.
Sending myself a notification is obviously not a good way to do moderation, but it worked for me, as the frequency of spams reduced as I started deleting them immediately.
Just because the spams reduced doesn't mean that I did good moderation, I was still getting spams at least once a week. It was then I decided to ask a question to the commenter, it's a simple one to answer if they are human. And even if the answer is wrong, I return an HTTP redirect response, this will trick the bots into thinking that they succeeded. I went with this approach as I would rather not implement captcha, there are no good accessibility friendly captchas out there!
I never received a spam since then, I probably have missed a few real comments if the visitor couldn't answer the question. It can be solved by adding the wrong answers to a separate table or something and moderating it later. But I don't think it is that important for my small and humble website.
In the future, I want the visitors to be able to reply to comments. I already have some work done for that in the backend, it will probably be released along with the webmention support I am working on at the moment!
The posted comments will be hidden until I review and approve it. But it would be a problem for the commenter if they can't see their own comment. So, for a slightly better user experience, the commenters can now see their comments even if it is not moderated yet, they can also edit or delete it if they'd like to.
This is done by storing a unique ID in a private cookie when someone comments for the first time and using it to connect to all their comments from then onwards. The ID is a randomly generated UUID.
My final SQL for the comment database looks like this:
CREATE TABLE IF NOT EXISTS comments (
id TEXT NOT NULL, -- random UUID
post TEXT NOT NULL, -- URL for the page
name TEXT NOT NULL, -- Optional name, defaulted to anonymous
email TEXT, -- optional email
website TEXT, -- optional website for the commenter
comment TEXT NOT NULL, -- the comment
commenter TEXT NOT NULL, -- random UUID
reply_to TEXT, -- something for the future threaded replies
date TEXT NOT NULL -- the created date, I could use the DATE type here though
is_moderated INTEGER NOT NULL, -- Integer because SQLite doesn't support boolean.
-- 1 means that the comment is moderated.
)
For now, I think this is sufficient for my needs, even providing comments is already an overkill for my small website.