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 pathname to title, 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. pathname or url avoids 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 pathname when paths are stable and unique; pick url when you need strict per-URL threads; pick title only 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.