Skip to content
Branch: master
Find file Copy path
Find file Copy path
3 contributors

Users who have contributed to this file

@dunglas @jdreesen @Spomky
116 lines (83 sloc) 5.14 KB

Getting Started

Subscriptions Schema

Starting the Hub

The easiest way to get started is to install the official Mercure Hub. When it's done, go directly to the next step. Also, keep in mind that the hub is entirely optional. By the specification, your app can implement the Mercure protocol directly (take a look to the libraries implementing Mercure).

In the rest of this tutorial, we'll assume that the hub is running on http://localhost:3000 and that the JWT_KEY is !ChangeMe!.


Subscribing to updates from a web browser or any other platform supporting Server-Sent Events is straightforward:

// The subscriber subscribes to updates for the topic
// and to any topic matching{id}
const url = new URL('');
url.searchParams.append('topic', '{id}');
url.searchParams.append('topic', '');
// The URL class is a convenient way to generate URLs such as{id}&topic=

const eventSource = new EventSource(url);

// The callback will be called every time an update is published
eventSource.onmessage = e => console.log(e); // do something with the payload

The EventSource class is available in all modern web browsers. And for legacy browsers, there are polyfills.

Closing Connection

It is important to close this connection between the client and the hub if it is no longer needed. Opened connections have a continuous buffer that will drain your application resources. This is especially true when using Single Page Applications (based on e.g. ReactJS): the connection is maintained even if the component that created it is unmounted.

if(eventSource !== null) {
    eventSource = null;

Sending Private Updates

Optionally, the authorization mechanism can be used to subscribe to private updates.

Authorization Schema

Discovering the Mercure Hub

Also optionally, the hub URL can be automatically discovered:

Discovery Schema

Here is a snippet to extract the URL of the hub from the Link HTTP header.

fetch('') // Has this header `Link: <>; rel="mercure"`
    .then(response => {
        // Extract the hub URL from the Link header
        const hubUrl = response.headers.get('Link').match(/<([^>]+)>;\s+rel=(?:mercure|"[^"]*mercure[^"]*")/)[1];
        // Subscribe to updates using the first snippet, do something with response's body...


To dispatch an update, the publisher (an application server, a web browser...) needs to send a POST HTTP request to the hub:

Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJtZXJjdXJlIjp7InN1YnNjcmliZSI6WyJmb28iLCJiYXIiXSwicHVibGlzaCI6WyJmb28iXX19.afLx2f2ut3YgNVFStCx95Zm_UND1mZJ69OenXaDuZL8

topic={"foo": "updated value"}

Example using Node.js / Serverless:

// Handle a POST, PUT, PATCH or DELETE request or finish an async job...
// and notify the hub
const https = require('https');
const querystring = require('querystring');

const postData = querystring.stringify({
    'topic': '',
    'data': JSON.stringify({ foo: 'updated value' }),

const req = https.request({
    hostname: '',
    port: '443',
    path: '/.well-known/mercure',
    method: 'POST',
    headers: {
        Authorization: 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJtZXJjdXJlIjp7InN1YnNjcmliZSI6WyJmb28iLCJiYXIiXSwicHVibGlzaCI6WyJmb28iXX19.afLx2f2ut3YgNVFStCx95Zm_UND1mZJ69OenXaDuZL8',
        // the JWT must have a mercure.publish key containing an array of targets (can be empty for public updates)
        // the JWT key must be shared between the hub and the server
        'Content-Type': 'application/x-www-form-urlencoded',
        'Content-Length': Buffer.byteLength(postData),
}, /* optional response handler */);

// You'll probably prefer use the request library or the node-fetch polyfill in real projects,
// but any HTTP client, written in any language, will be just fine.

The JWT must contain a publish property containing an array of targets. This array can be empty to allow publishing anonymous updates only. To create and read JWTs try (demo token, key: !ChangeMe!).

Going Further

Read the full specification

You can’t perform that action at this time.