Introduction#

While looking through comment systems for static blogs, I decided to check out Cusdis. It promises a “low-friction” approach: a simple widget, no ads, and no heavy tracking in the background. Cusdis positions itself as a lightweight, privacy-friendly alternative to Disqus. It is an open-source project with a self-hosting option and a managed version at cusdis.com. You can find a detailed guide on how to self-host Cusdis in a separate post: Self-Hosting Cusdis on a VPS.

My goal was to check two things. First, how to do a sensible integration with Hugo (without just pasting scripts randomly). Second, what is the real performance overhead on the page when comments are enabled.

Cusdis in Practice#

Cusdis is designed as a minimalist, embeddable comment widget for small websites, including static blogs. In practice, we get comments without forcing the user to log in. Also, the project claims it doesn’t use cookies. For many people, this is crucial when it comes to privacy and compliance.

From a product perspective, you can see consistency here. The authors focus on a small SDK (just a few kilobytes after gzip), built-in i18n, and dark mode support, rather than building huge “platform” features. There is also an operational aspect. Cusdis offers email notifications about new comments and quick moderation mechanisms directly from a link in the email. This really shortens the reaction time.

Integration with Hugo#

Instead of hardcoding the code into the template, I used a partial. This gives me control over parameters from hugo.toml and allows me to easily move the configuration between environments. Because of this, when I change the host or App ID, I don’t touch the view layer.

I kept the layouts/partials/comments/cusdis.html file quite neutral. It uses page parameters (URL, title, unique ID) because these decide if the comment thread will be correctly “pinned” to a specific post.

{{- $cusdis := .Site.Params.cusdis -}}
{{- $lang := .Site.Language.Lang | default "en" -}}

<div id="cusdis_thread"
  data-host="{{ $cusdis.host }}"
  data-app-id="{{ $cusdis.appId }}"
  data-page-id="{{ .File.UniqueID }}"
  data-page-url="{{ .Permalink }}"
  data-page-title="{{ .Title }}"
  data-lang="{{ $lang }}"
  data-theme="dark"
></div>
<script async defer src="{{ $cusdis.host }}/js/cusdis.es.js"></script>

I moved the configuration to hugo.toml so it can be changed without rebuilding the layouts. The self-hosted variant points to the host where we have our Cusdis service. The cloud variant simply uses https://cusdis.com.

[params]
  commentSystem = "cusdis"

[params.cusdis]
  host = "https://comments.yourdomain.com"  # or https://cusdis.com for the cloud service
  appId = "your-app-id-here"

To keep the code clean, I added a simple “dispatcher” at the layouts/partials/comments.html level. This is a small thing, but in practice, it makes life much easier. Switching the comment system takes one line in the config, and the rest of the layouts stay untouched.

{{- $commentSystem := .Site.Params.commentSystem -}}

{{- if eq $commentSystem "cusdis" -}}
  {{ partial "comments/cusdis.html" . }}
{{- else if eq $commentSystem "giscus" -}}
  {{ partial "comments/giscus.html" . }}
{{- else if eq $commentSystem "disqus" -}}
  {{ partial "comments/disqus.html" . }}
{{- end -}}

Performance and Moderation#

In my tests, I compared the baseline (no comments) with the version where Cusdis is enabled. For me, it resulted in an increase from 11 to 15 requests, +24 KB in transfer (311 KB → 335 KB), and +0.83 s in load time (1.20 s → 2.03 s). I treat these numbers as “my specific case”. They will depend on cache, compression, latency to the host, and whether we are talking about the size after gzip or the transfer reported by the browser’s developer console.

What I appreciated on the operational side is the simplicity of moderation. Cusdis has a flow where I get an email notification about a comment and I can quickly approve it. I don’t need to click through a heavy admin panel. If I self-host, I also have an infrastructure argument: the data and control are on my side. Cusdis is self-hostable and by definition doesn’t try to lock me into a vendor lock-in.

However, it is worth knowing that styling can be less comfortable. The widget renders in an iframe. This limits the classic approach of “just add CSS in the theme and you’re done”. In practice, this mostly ends with either accepting the dark/light look, editing styles on the instance side (when self-hosting), or maybe writing custom JS if we really want to align everything perfectly with our design system. Here you can see how to inject custom styles into an iframe using JS code.

When It Makes Sense#

Cusdis is a good fit for static blogs and websites where simplicity, low overhead, and privacy are priorities, and manual moderation is an acceptable cost. Cusdis purposely does not try to be a “full Disqus”. It wants to be a minimalist, embeddable comment system for small websites. If this is what you are looking for, this product decision works in its favor.

If you need advanced social features (social login, rich editor, complex threads like on GitHub), you will probably hit a wall quickly. In that case, it is better to consider alternatives right away. On the other hand, if you just want to have comments, without cookies, without a heavy script, and with a sensible moderation flow, Cusdis is a pragmatic choice.