Add comments to Static blog like Hugo, Jekyll with Isso
Isso Introduction
Isso is a Disqus alternative commenting server for static web sites. It is a lightweight commenting server written in Python and JavaScript. It aims to be a drop-in replacement for Disqus.
The benefits of Isso compare to Disqus:
- Smaller, javascript is 64kb compressed. faster loading speed compare to Disqus.
- You own your data. comments stored in your server sqlite3 database.
- No 3rd party code run on your site. 3rd party comment system can run whatever code on your site.
Features
- Add/Reply/Like/Dislike comments.
- Comments written in Markdown
- Users can edit or delete own comments (within 15 minutes by default).
- Comments in moderation queue are not publicly visible before activation.
- anonymous comments
- privacy, not log exact IP
- Disqus & WordPress Import. You can migrate your Disqus/WordPress comments without any hassle.
- SQLite backend.
- Embed a single JS file, 65kB (20kB gzipped) and you are done.
- Supports Firefox, Safari, Chrome and IE10.
Isso Setup
To setup Isso, you need following:
- A server. If your site traffic is low, a very small server is enough.
- A domain name for Isso server.
The first step is downloading the latest Isso source:
git clone https://github.com/posativ/isso.git
The easy way is use docker to run Isso.
Build docker image by docker build
:
$ docker build . -t isso
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
isso latest 1234b841c0ac 4 hours ago 139MB
Then we need config Isso.
The Isso configuration file is an INI-style
textfile. It reads integers, booleans, strings and lists.
The default isso configuration: isso.conf
Here is my config:
[general]
; database location, check permissions,
; automatically created if it does not exist
dbpath = /db/isso_comments.db
; your website or blog (not the location of Isso!)
host = https://yourdomain.tld/
[admin]
; admin interface in /admin
enabled = true
password = abc123
[guard]
; basic spam protection
enabled = true
; limit to N new comments per minute.
ratelimit = 5
; how many comments directly to the thread
direct-reply = 3
; allow commenters to reply to their own comments when they could still edit the comment.
reply-to-self = false
require-author = false
require-email = false
Hints:
dbpath
andhost
is mandatory.dbpath
is the full path of sqlite3 database.host
is your site URL (includehttp://
orhttps://
). It can have multiple values. config it correctly to avoid cross domain attack (CORS).- Enable admin to manage comment through web interface.
- Enable guard to avoid spam.
Create config
and db
directory to store config and database.
mkdir -p config db
Put config file to config/isso.cfg
then run Isso in docker:
docker run -d --rm --name isso -p 127.0.0.1:8080:8080 -v `pwd`/config:/config -v `pwd`/db:/db isso
Note: Do not run Isso on a public interface.
Next step is config nginx to proxy traffic to Isso.
Add a nginx virtual server config /etc/nginx/sites-enabled/isso.conf
like following:
#
# /etc/nginx/sites-enabled/isso.conf
#
server {
server_name comments.yourdomain.tld;
location / {
proxy_pass http://localhost:8080;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Then restart nginx:
sudo systemctl restart nginx
To test server is running by curl /admin
, you should see HTTP 200
response:
$ curl -I https://comments.yourdomain.tld/admin
HTTP/2 200
Add comments to hugo
Inside hugo content.html
page, add following code at end of article to load isso.
<div style="max-width: 80%;">
<h3>Comments</h3>
<script data-isso="//comments.yourdomain.tld/" src="//comments.yourdomain.tld/js/embed.min.js"></script>
<section id="comments"></section>
</div>
By default, isso make the comment center align, if you want to it left align, you can override its css like following:
<div style="max-width: 80%;">
<h3>Comments</h3>
<script data-isso="//comments.yourdomain.tld/" src="//comments.yourdomain.tld/js/embed.min.js"></script>
<style>
.isso-postbox {
margin: 0 !important;
max-width: none !important;
}
#isso-root .isso-comment {
max-width: none !important;
margin: 0 !important;
}
</style>
<section id="comments"></section>
</div>
That’s it. Hugo have a comment system powered by Isso.
Isso Internal
API
Isso provide JSON API:
GET /?uri=
fetch comments foruri
.POST /preview
Preview post.POST /new
Create new comment.GET /id/<id>
Get comment by id.PUT /id/<id>
Delete comment by id.DELETE /id/<id>
Delete comment by id.POST /id/<id>/like
Like.POST /id/<id>/dislike
Dislike.
Database
Isso use sqlite3 as database. There are three tables in database:
- comments
- preferences
- threads
Table schema:
sqlite> .schema comments
CREATE TABLE comments (
tid REFERENCES threads(id),
id INTEGER PRIMARY KEY,
parent INTEGER,
created FLOAT NOT NULL,
modified FLOAT,
mode INTEGER,
remote_addr VARCHAR,
text VARCHAR,
author VARCHAR,
email VARCHAR,
website VARCHAR,
likes INTEGER DEFAULT 0,
dislikes INTEGER DEFAULT 0,
voters BLOB NOT NULL,
notification INTEGER DEFAULT 0
);
CREATE TRIGGER remove_stale_threads
AFTER DELETE ON comments
BEGIN
DELETE FROM threads
WHERE id NOT IN (SELECT tid FROM comments);
END;
sqlite> .schema threads
CREATE TABLE threads (
id INTEGER PRIMARY KEY,
uri VARCHAR(256) UNIQUE,
title VARCHAR(256)
);
sqlite> .schema preferences
CREATE TABLE preferences (
key VARCHAR PRIMARY KEY,
value VARCHAR
);
Sample data in database:
sqlite> .head on
sqlite> select * from comments;
tid|id|parent|created|modified|mode|remote_addr|text|author|email|website|likes|dislikes|voters|notification
1|1||1613999513.18983||1|5a01:21f3:c311:0000:0000:0000:0000:0000|First comment.||||0|0||0
sqlite> select * from threads;
id|uri|title
1|/blog/fun/|
sqlite> select * from preferences;
key|value
session-key|123456789012345678901234567890123456789056781234
Related pages:
- Demystifying Hugo Shortcodes: Your Ultimate Guide
- Hugo: How to escape shortcode in markdown
- Tips on Hugo SEO
- Custom hugo RSS template
- Hugo troubleshooting: execute of template failed: can't give argument to non-function
- Add git commit date as last update date in hugo page
References

OmniLock - Block / Hide App on iOS
Block distractive apps from appearing on the Home Screen and App Library, enhance your focus and reduce screen time.

DNS Firewall for iOS and Mac OS
Encrypted your DNS to protect your privacy and firewall to block phishing, malicious domains, block ads in all browsers and apps