How utterances Matches a Page to a GitHub Issue
Updated
utterances finds the GitHub issue for a page by running a GitHub issue search when the widget loads, using one of three page identifiers you choose during setup: the full url, the pathname, or the page title. If no matching issue exists, nothing breaks — the utterances-bot creates one the first time someone comments. This applies to any page where you embed the widget and have configured a repository and a mapping option.
The matching flow
1. You pick the identifier at configuration time
The widget needs to know which piece of page data to search on. utterances supports three options:
| Mapping option | What is sent to the search | Best when |
|---|---|---|
url |
The full page URL | Pages have stable, unique URLs and you want exact matching |
pathname |
The URL path only (e.g. /blog/post-1) |
The same path is served from multiple hosts or protocols |
title |
The page title | URLs change often but titles stay stable |
The choice is part of the embed configuration, so it is fixed per site (or per widget instance) rather than decided at runtime by the reader.
2. On load, the search API runs
When the utterances script initializes, it queries the GitHub issue search API for an issue in your configured repository that corresponds to the selected identifier. The result is the issue whose comments become the widget's comment thread.
3. No match is not an error
If the search returns nothing — a brand-new post, for example — the widget simply shows an empty thread. The issue is not created at page load; it is created lazily.
4. First comment creates the issue
The first time a reader submits a comment, utterances-bot opens an issue in your repository for that page. From then on, the same identifier resolves to that issue, and all subsequent comments land there.
Why the identifier choice matters
The identifier is effectively the join key between a page and an issue. Two consequences follow:
- Changing the mapping later orphans threads. If you switch from
pathnametotitle, existing issues were created under the old key and will no longer be found, so old comments appear to vanish from the page (they still exist in the repository). - Collisions are possible. Two pages that share a
title(common with generic titles like "Home" or "Archive") will map to the same issue and share one comment thread.pathnameorurlavoids this when paths are unique.
A practical example: a docs site with pages at /docs/install and /docs/config is safe with pathname, because each path is distinct. A blog where every post is titled with the post name is also safe with title, but a blog with a shared suffix in titles is not.
Commenting and authorization
To post through the widget, a reader must authorize the utterances app via the GitHub OAuth flow so it can post on their behalf. Readers who prefer not to authorize can comment directly on the GitHub issue itself, and those comments appear in the widget because the widget reads the same issue thread.
What this design implies for you
- Your repository is the database. All comment data lives in GitHub issues, so moderation, search, and export happen through GitHub's own tools.
- The widget is read-mostly until first comment. Loading a page performs a search; it does not create issues, so empty threads cost you nothing in repository clutter until someone actually engages.
- Plan the identifier before launch. Pick
pathnamewhen paths are stable and unique; pickurlwhen you need strict per-URL threads; picktitleonly when titles are reliably unique and URLs are not.
The site lists real deployments such as Haxe documentation and cookbook, sadsloth.net, and danyow.net, which is a reasonable signal that the pathname/url approach holds up across documentation and personal blog structures.