Thread identity
Every comment belongs to a thread, and Charcha works out which thread from the address of the page the comment was posted on. That derived value is the page key. Two readers have to land on the same key or they will not see each other’s comments.
Most of the time you will never think about this. The page is here for the times you have to, because a couple of the rules are opinionated and one of them catches people out.
What counts and what does not
Section titled “What counts and what does not”| Part of the URL | Decides the thread? |
|---|---|
Path (/notes/hello) |
Yes. This is the identity |
| Uppercase against lowercase in the path | Yes. /Post and /post are different threads |
https:// against http:// |
No |
| Domain, subdomain, port | No |
| Trailing slash | No. /post and /post/ are the same thread |
?anything=here |
No |
#section |
No |
The domain is ignored
Section titled “The domain is ignored”One Charcha deployment serves one site, so the domain carries nothing worth keeping.
Dropping it makes example.com, www.example.com, the http:// version and
localhost:4321 while you are drafting all one conversation, with nothing to
configure. Move your blog to a new domain and the comments come with it.
So is the query string
Section titled “So is the query string”If ?utm_source=newsletter counted, one post shared through three channels would
become four conversations and none of the readers would see each other. Tracking
parameters are unbounded and people keep inventing more, so every parameter is
dropped.
That costs you something if your site uses the query string for real identity.
/blog?page=2 and /item?id=42 collapse into a single shared thread, and there is no
setting yet that keeps a named parameter. Give those pages an explicit thread id
instead, which is the section below. If a parameter does become keepable later,
order still will not matter: whatever survives is sorted before the key is built, so
?a=1&b=2 and ?b=2&a=1 cannot drift into two threads.
The one that will surprise you: case matters
Section titled “The one that will surprise you: case matters”/my-post and /My-Post are two different threads.
That is deliberate. Web standards make only the domain case-insensitive, and static
hosts really do serve /My-Post and /my-post as different pages, so folding them
together would merge two real pages into one comment thread.
The rule behind that choice, and behind several others here:
Splitting one page into two threads is recoverable. Merging two pages into one thread is not.
A comment on the wrong key can be moved. Comments from two pages already mixed together cannot be told apart again. So Charcha splits whenever the answer is ambiguous.
In practice this only bites if your own links are inconsistently cased. There is no setting that folds two casings back together, so the fix is to make the links agree.
Naming a thread yourself
Section titled “Naming a thread yourself”When the URL is the wrong identity, a page that moved, a paginated route, a post reachable at two paths, name the thread and the URL stops mattering:
<div id="charcha" data-thread="leaving-the-comment-industry"></div>The value has to be ASCII, start with a letter or digit, and run to no more than 200 characters.
Explicit ids live in their own namespace and cannot collide with a URL-derived key.
URL keys always begin with /, explicit ids are stored as id:<your-value>. That
separation matters because data-thread arrives from the page like everything else,
and without it a crafted value could be aimed at another page’s thread.
Once you set data-thread on a page, keep it. Take it away and the page goes back to
its URL-derived key, leaving the existing comments behind on the old one.
The key is worked out in the Worker
Section titled “The key is worked out in the Worker”Always. The embed reports the page address and nothing more. It cannot send a key directly, and nothing a browser submits can choose one Charcha would not have produced itself. Anything arriving from a page is attacker-controlled, and the key is unique across the database, so accepting one over the wire would let anybody graft comments onto any thread they liked.
Deriving it in one place has a second effect you benefit from quietly: a reader with a cached copy of an older embed still gets today’s rules rather than the ones that shipped with it.
The limits are enforced rather than advisory. A reported URL is capped at 2,048 characters, an explicit thread id at 200, and the resulting key at 512. A URL containing control characters is refused outright rather than cleaned up, and text is Unicode-normalised so that two identical-looking addresses cannot become two threads.