Skip to content

docs: rewrite for the 1.0 protocol release#1238

Closed
dunglas wants to merge 8 commits into
spec/topic-selectorsfrom
docs/v1.0
Closed

docs: rewrite for the 1.0 protocol release#1238
dunglas wants to merge 8 commits into
spec/topic-selectorsfrom
docs/v1.0

Conversation

@dunglas

@dunglas dunglas commented May 5, 2026

Copy link
Copy Markdown
Owner

Summary

A full rewrite of the user-facing documentation for the 1.0 release of the Mercure protocol, aligned with the typed-matcher model and object-form JWT claims (#959).

The rewrite is split across three commits:

  1. Documentation rewrite for 1.0 — replaces every snippet that used the 0.x topic= query parameter with the new match= / matchURLPattern= / matchRegexp= / matchCEL= / matchURITemplate= typed parameters. JWT examples switch to the object-form mercure.publish and mercure.subscribe claims, and references to the new /.well-known/mercure/subscriptions/{matchType}/{match}/{subscriber} topic shape.

    Restructures the docs tree into Getting Started, Concepts, Use Cases, Deployment, Production, Reference, and Ecosystem. Adds two new AI-focused guides — LLM token streaming (with a concrete OpenAI / Anthropic / local-model walk-through) and AI agent progress streaming. Adds a thorough UPGRADE.md section for 0.x → 1.0 with greppable find-and-replace patterns, plus docs/redirects.json mapping every old URL to its new home for the Next.js site.

  2. SEO and LLM ingestion optimization — adds YAML frontmatter (title + description) to every page, rewrites generic H2/H3 headings to be topic-specific, tags every code block with an explicit language, and prepends a one-line comment indicating purpose. Adds llms.txt at the repo root following the llmstxt.org convention.

  3. Real filename comments in code blocks — where a block is a recognizable file (Compose, Helm values, NGINX config, HAProxy config, GitHub Actions workflow, full HTML, the canary script), the heading-derived comment is replaced with the actual filename (# compose.yaml, # values.yaml, # /etc/nginx/conf.d/mercure.conf, etc.).

Scope

  • 36 markdown files rewritten + 1 new redirects.json + new llms.txt.
  • No spec changes — spec/mercure.md is untouched in this PR.
  • No code changes outside docs/.
  • All inter-doc anchors verified: 0 broken file links, 0 broken anchors.

Out of scope

dunglas added 4 commits April 30, 2026 02:25
The hub publishes subscription events on relative topic IDs
(e.g., /.well-known/mercure/subscriptions/...). Requiring patterns
to be absolute prevents subscribers from matching those topics
with matchURLPattern.
The docs are restructured into Getting Started, Concepts, Use Cases,
Deployment, Production, Reference, and Ecosystem. All content reflects
the typed-matcher protocol (match/matchURLPattern/matchRegexp/...) and
the new object-form mercure.publish and mercure.subscribe JWT claims.

New material covers LLM token streaming, AI agent progress, the
Postgres/Redis/Kafka/Pulsar transports, rolling updates and graceful
shutdown, health monitoring with the transport-aware probes, and a
0.x-to-1.0 migration manual in UPGRADE.md.

A redirects.json file mirrors every old URL to its new home so the
Next.js site can keep external links working.
Add YAML frontmatter (title + description) to every Markdown page so
search engines and AI agents have explicit per-page metadata. Rewrite
generic H2 and H3 headings to be topic-specific ("## Run the Mercure
Hub Locally with Docker" instead of "## Run the hub"), which keeps
chunked context clear when a single section is retrieved out of
context.

Tag every code block with an explicit language and prepend a one-line
comment describing what the block does, so AI parsers can identify
filenames and intent without surrounding prose. JSON snippets switch
to jsonc to allow the comment without breaking parsers.

A new llms.txt at the repo root indexes the documentation by topic
(core concepts, setup, AI use cases, production, reference) with
absolute https://mercure.rocks URLs, following the llmstxt.org
convention.
…icable

Where a code block clearly is a real file — Compose service definition,
Helm values, NGINX config, HAProxy config, GitHub Actions workflow, full
HTML page, the canary shell script — the first-line comment is now the
actual filename instead of the surrounding section heading. Illustrative
snippets (JSON examples, JS fragments, shell command lines) keep the
heading-derived purpose comment.

Also remove blank lines that an earlier pass mistakenly inserted after
in-block comment lines, and restore the shebang on the canary script.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR rewrites and restructures the Mercure user-facing documentation for the 1.0 protocol release, updating examples to the typed-matcher subscription model and object-form JWT claims, and reorganizing the docs tree into clearer conceptual/deployment/reference sections. It also introduces LLM/AI-agent streaming guides, adds site redirect mappings, and includes an llms.txt index for LLM ingestion.

Changes:

  • Rewrite docs to Mercure 1.0 semantics (typed match* query params, object-form mercure.publish / mercure.subscribe JWT claims, subscription event topic shapes).
  • Restructure documentation into new sections (Getting Started, Concepts, Use Cases, Deployment, Production, Reference) and add multiple new guides/pages.
  • Add docs/redirects.json for URL migrations and add a repo-root llms.txt for LLM-friendly indexing.

Reviewed changes

Copilot reviewed 59 out of 59 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
spec/mercure.md Updates URL Pattern matcher guidance to allow relative patterns/topics with hub URL as base.
llms.txt Adds an LLM-ingestion oriented index of key Mercure docs pages.
docs/use-cases/README.md Adds Use Cases landing page with categorized links.
docs/use-cases/notifications.md Adds a notifications walkthrough (per-user + broadcast patterns).
docs/use-cases/llm-token-streaming.md Adds an LLM token streaming guide with concrete provider examples.
docs/use-cases/live-data.md Adds a live data/dashboard guide emphasizing URL Patterns and fan-out.
docs/use-cases/hotwire.md Adds Hotwire/Turbo Streams integration guide using Mercure as transport.
docs/use-cases/graphql.md Adds a GraphQL-over-Mercure guide and Apollo client transport example.
docs/use-cases/collaborative-editing.md Adds collaborative editing guide (CRDT + presence + replay patterns).
docs/use-cases/async-jobs.md Adds async jobs/progress streaming guide with replay considerations.
docs/use-cases/ai-agent-progress.md Adds structured AI agent progress/state streaming guide.
docs/spec/use-cases.md Removes legacy spec “use cases” page (content relocated/replaced).
docs/spec/faq.md Removes legacy spec FAQ page (replaced by new reference FAQ).
docs/reference/protocol.md Adds protocol overview/orientation page linking to the canonical spec.
docs/reference/license.md Adds updated licensing page (protocol vs hub licensing).
docs/reference/faq.md Adds new FAQ page (comparisons, limits, common questions).
docs/redirects.json Adds redirects mapping old docs URLs to the new structure.
docs/README.md Replaces docs index with the new structure and updated navigation.
docs/production/troubleshooting.md Adds production troubleshooting guide (401/403/CORS/reconnect/etc.).
docs/production/rolling-updates.md Adds graceful shutdown / rollout guidance for SSE workloads.
docs/production/load-testing.md Adds Gatling load testing guide and operational bottleneck checklist.
docs/production/high-availability.md Adds HA/multi-node transport guidance and Cloud/Self-Hosted options.
docs/production/health-monitoring.md Adds health endpoints, probes, Prometheus/Grafana monitoring guidance.
docs/production/debugging.md Adds pprof-based debugging guide for the hub.
docs/mercure.md Removes legacy “Mercure in a Few Words” page (replaced by introduction).
docs/introduction.md Adds new introductory landing page aligned to 1.0 docs structure.
docs/hub/troubleshooting.md Removes legacy hub troubleshooting page (replaced by production troubleshooting).
docs/hub/traefik.md Removes legacy Traefik page (replaced by deployment reverse-proxy guide).
docs/hub/rolling-updates.md Removes legacy rolling updates page (replaced by production rolling-updates).
docs/hub/nginx.md Removes legacy NGINX page (replaced by deployment reverse-proxy guide).
docs/hub/load-test.md Removes legacy load test page (replaced by production load-testing).
docs/hub/license.md Removes legacy hub license page (replaced by reference/license).
docs/hub/install.md Removes legacy install page (replaced by getting-started/installation).
docs/hub/debug.md Removes legacy debug page (replaced by production/debugging).
docs/hub/cookbooks.md Removes legacy cookbooks page (content reorganized into new sections).
docs/hub/cloud.md Removes legacy cloud page (content reorganized into production/HA + reference).
docs/getting-started/quickstart.md Adds new quickstart using 1.0 matcher/JWT examples.
docs/getting-started/installation.md Adds new installation guide (Docker/Compose/Helm/binary/etc.).
docs/getting-started.md Removes legacy getting started page (replaced by new getting-started section).
docs/ecosystem/hotwire.md Removes legacy ecosystem Hotwire page (replaced by use-cases/hotwire).
docs/ecosystem/help.md Removes legacy help page (help info relocated into new docs index/FAQ).
docs/ecosystem/github-actions.md Removes legacy GitHub Actions page (replaced by deployment/github-actions).
docs/ecosystem/conformance-tests.md Expands and modernizes conformance test documentation (Playwright, config, scope).
docs/deployment/reverse-proxy.md Adds consolidated reverse-proxy configurations for SSE correctness.
docs/deployment/kubernetes.md Adds Helm-based Kubernetes deployment guidance (probes, rootless, ingress).
docs/deployment/github-actions.md Adds service-container based GitHub Actions setup instructions.
docs/deployment/docker.md Adds Docker/Compose deployment guide (healthchecks, rootless, volumes).
docs/deployment/configuration.md Adds configuration reference (directives, env vars, transports, JWKS, tuning).
docs/concepts/topics-and-matchers.md Adds 1.0 matcher model explanation and guidance on choosing matchers.
docs/concepts/subscribing.md Adds client subscription guide (EventSource + fetch-event-source + examples).
docs/concepts/reconnection-and-history.md Adds replay/Last-Event-ID/bootstrapping/history sizing guidance.
docs/concepts/publishing.md Adds publish API guide (fields, alternates, private updates, auth).
docs/concepts/encryption.md Adds JWE end-to-end encryption guide and key distribution patterns.
docs/concepts/active-subscriptions.md Adds subscription events + subscription API presence guide.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread docs/concepts/active-subscriptions.md Outdated
Comment thread docs/use-cases/graphql.md
Comment thread docs/use-cases/graphql.md Outdated
Comment thread docs/deployment/kubernetes.md
Comment thread docs/deployment/kubernetes.md Outdated
Comment thread docs/deployment/kubernetes.md Outdated
Comment thread spec/mercure.md
dunglas added 2 commits May 5, 2026 11:27
Three changes from the PR review:

- Drop "REST-ish" — the subscription API is REST: HTTP, resource URLs,
  GET, JSON-LD bodies. No qualification needed.
- Recommend cookies first for browsers in the authorization guide.
  HttpOnly + Secure + SameSite is more native and more secure than the
  bearer header for browser EventSource, and the bearer header isn't
  even available there. Reframe the section as "pick the method that
  matches your client": cookie for browsers, header for non-browser
  clients, query parameter as a last resort.
- Normalize Title Case across 132 H2 / H3 / H4 headings. Lowercase
  short stop words (a, an, the, and, but, or, nor, for, so, yet, of,
  in, on, at, by, to, up, as, vs, off, out, via, with, from). Preserve
  inline-code identifiers (lastEventID, minReadySeconds,
  USE_FORWARDED_HEADERS, /healthz, etc.) verbatim.

All inter-doc anchors verified after the rename: 0 broken file links,
0 broken anchors.
Drop em-dashes, en-dashes, ellipses, curly quotes, the typographic
multiplication and section signs, and Unicode arrows / box-drawing in
favor of ASCII equivalents:

- Em-dashes (325) reworked into colons, periods, parentheses, or
  semicolons depending on context. Comma-splice cases produced by the
  mechanical pass were rewritten by hand sentence by sentence.
- The six ASCII-art diagrams (quickstart, encryption, llm-token-streaming,
  live-data, async-jobs, graphql) redrawn with `+`, `-`, `|`, `<`, `>`,
  `^`, `v`. No box-drawing characters or block shapes remain.
- En-dashes became hyphens; ellipses became `...`; arrows in prose
  became `->`.
- Math operators in prose normalised: `≥` -> `>=`, `×` -> `x`,
  `§` -> `section`. Currency `€` is kept where it carries meaning.

Also a small content fix: drop the "REST-ish API" hedge in
active-subscriptions.md since the subscription API is plain REST.
@Lea-Bar

Lea-Bar commented May 5, 2026

Copy link
Copy Markdown

Une documentation de la bonne pratique (avec explication de pourquoi on utilise des URL etc...) peut être bien pour que les nouvelles personnes initié à Mercure puisse le prendre en main correctement.

dunglas added 2 commits May 5, 2026 21:37
Apply sentence case across every H1-H6 heading and the frontmatter
`title` field in 37 markdown files: capitalize the first word of the
heading and the first word after sentence-ending punctuation
(`.`/`?`/`!`); keep proper nouns and brand names (Mercure, Docker,
Kubernetes, GraphQL, OpenAI, ...), acronyms (JWT, SSE, HTTP, CORS,
...), and inline-code identifiers (lastEventID, minReadySeconds,
USE_FORWARDED_HEADERS, ...) at their canonical casing; lowercase
everything else.

Targeted hand fixes for cases the generic pass missed: AGPL-3.0
preserved through hyphenation, Server-Sent Events, Pusher, Ably,
Firebase Realtime Database, Turbo Streams as a proper noun phrase,
and "Where to go next" instead of "Go" the language.

Same treatment applied to llms.txt section headers and link labels.

All inter-doc anchors verified after the case change: 0 broken file
links, 0 broken anchors.
- active-subscriptions: drop the misleading `withCredentials` query
  parameter; it's an `EventSource` option, not a hub parameter.
- graphql: import `Observable` from `@apollo/client`; restructure the
  Apollo SSE link so the teardown function actually reaches the
  Observable. The teardown now closes the `EventSource` if it opened
  and aborts the discovery `fetch` if it didn't, so unsubscribe
  reliably terminates the subscription.
- kubernetes: fix the Helm install command and the `values.yaml`
  example to match the chart's real keys (`publisherJwtKey`,
  `subscriberJwtKey`, `extraDirectives`, `existingSecret`); drop the
  Go-template syntax that Helm doesn't render in values files; switch
  the production example to `replicaCount: 1` since the open-source
  build only supports BoltDB and multi-replica without a clustered
  transport doesn't deliver consistent updates. The Self-Hosted
  example below now sets `replicaCount: 3` alongside the Redis
  transport, where it's actually correct.
- topics-and-matchers: expand the topics section with a "why URLs"
  rationale (REST, RFC 3986, hypermedia composability, tooling) and a
  parallel "when a non-URL identifier is fine" section showing slugs,
  UUIDs, and custom URN schemes matched with `matchExact` /
  `matchRegexp`.

Also fix two intra-doc anchor links that pre-existing heading renames
broke: quickstart's `#subscribe` / `#publish` and configuration's
`#transports`.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 59 out of 59 changed files in this pull request and generated 8 comments.

Comment thread spec/mercure.md
Comment on lines +166 to +170
URL patterns **MAY** be absolute (e.g., `https://example.com/books/:id`) or relative
(e.g., `/.well-known/mercure/subscriptions/Exact/:topic/:subscriber`). When evaluating
a relative pattern or a relative topic, the hub **MUST** use the hub's URL as the
base URL. This allows subscribers to match relative topics published by the hub
itself, such as subscription events (see (#subscription-events)).
```console
# Publish a Mercure Update with curl
curl -X POST http://localhost:8080/.well-known/mercure \
-H 'Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJtZXJjdXJlIjp7InB1Ymxpc2giOlsqXX19.iHLdpAEjX4BqCsHJEojDSWQRDdDOGqwmuh9XbmAjxBo' \
Comment on lines +77 to +84
# Publisher: a Python agent
import json
import requests
from openai import OpenAI

HUB = "https://hub.example.com/.well-known/mercure"
PUBLISHER_JWT = os.environ["MERCURE_PUBLISHER_JWT"]

Comment on lines +91 to +97
rows = []
for i, batch in enumerate(query_batches(filters)):
rows.extend(batch)
publish(
topic, {"type": "progress", "percent": i * 100 // batch_count},
alternate=user_topic, private=True,
)
Comment on lines +8 to +12
Mercure is a public protocol, not just an implementation. The canonical source of truth is the [IETF Internet-Draft](https://datatracker.ietf.org/doc/draft-dunglas-mercure/), on track for publication as an RFC. The full text is also kept in this repository:

- **[The Mercure Protocol specification](../../spec/mercure.md)**
- [OpenAPI definition](https://github.com/dunglas/mercure/blob/master/spec/openapi.yaml)

Comment thread docs/reference/license.md
Comment on lines +10 to +13
- The **Mercure protocol** is open. Anyone can implement it, including in proprietary software.
- The **Mercure.rocks Hub** is licensed under [AGPL-3.0](https://github.com/dunglas/mercure/blob/master/LICENSE). Modifications to the hub itself must be shared.
- **Software that uses the hub** (publishers, subscribers, your application) is **not affected** by the AGPL. Use any license you want: proprietary, MIT, GPL, anything.
- For organizations that can't use AGPL software, [commercial licenses are available](https://mercure.rocks/pricing).
Comment thread docs/reference/license.md
Comment on lines +19 to +22
## The Mercure.rocks reference hub license

The Mercure.rocks Hub (this repository) is [AGPL-3.0](https://github.com/dunglas/mercure/blob/master/LICENSE).

Comment thread docs/use-cases/README.md
Comment on lines +1 to +3
---
title: "Mercure use cases: AI streaming, real-time uis, and collaboration"
description: "Practical Mercure use cases including LLM token streaming, AI agent progress, live data, collaborative editing, async jobs, and notifications."
@dunglas

dunglas commented May 29, 2026

Copy link
Copy Markdown
Owner Author

Heads-up: the spec has changed substantially in #1262 (two matcher types: Exact + URL Pattern; OAuth 2.0 authorization via authorization_details; alternate topics removed; topic/topicURLPattern subscribe parameters). These docs describe the earlier design and need updating to match before merge. Leaving open with this note.

@dunglas

dunglas commented Jun 15, 2026

Copy link
Copy Markdown
Owner Author

Superseded by #1278, which documents the current OAuth 2.0 / two-matcher protocol (the spec and code this PR targeted have since changed). Closing.

@dunglas dunglas closed this Jun 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants