docs: rewrite for the 1.0 protocol release#1238
Conversation
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.
There was a problem hiding this comment.
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-formmercure.publish/mercure.subscribeJWT 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.jsonfor URL migrations and add a repo-rootllms.txtfor 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.
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.
|
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. |
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`.
| 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' \ |
| # 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"] | ||
|
|
| 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, | ||
| ) |
| 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) | ||
|
|
| - 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). |
| ## The Mercure.rocks reference hub license | ||
|
|
||
| The Mercure.rocks Hub (this repository) is [AGPL-3.0](https://github.com/dunglas/mercure/blob/master/LICENSE). | ||
|
|
| --- | ||
| 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." |
|
Heads-up: the spec has changed substantially in #1262 (two matcher types: Exact + URL Pattern; OAuth 2.0 authorization via |
|
Superseded by #1278, which documents the current OAuth 2.0 / two-matcher protocol (the spec and code this PR targeted have since changed). Closing. |
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:
Documentation rewrite for 1.0 — replaces every snippet that used the 0.x
topic=query parameter with the newmatch=/matchURLPattern=/matchRegexp=/matchCEL=/matchURITemplate=typed parameters. JWT examples switch to the object-formmercure.publishandmercure.subscribeclaims, 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.mdsection for 0.x → 1.0 with greppable find-and-replace patterns, plusdocs/redirects.jsonmapping every old URL to its new home for the Next.js site.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.txtat the repo root following the llmstxt.org convention.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
redirects.json+ newllms.txt.spec/mercure.mdis untouched in this PR.docs/.Out of scope
docs/redirects.jsonis out of this repository.