2 min read

Presentation API

The Presentation API allows a web application to control a secondary display (like a projector or a connected TV) and display web content on it. This enables dual-screen experiences where the primary screen (laptop/phone) acts as a controller and the secondary screen displays the presentation.

1. The Concept

The API distinguishes between two contexts:

  1. Controller: The page initiating the presentation (e.g., on a laptop).
  2. Receiver: The page being displayed on the secondary screen.

2. The Controller (Sender)

To start a presentation, you create a PresentationRequest with the URL of the page you want to show.

// 1. Create a request
const request = new PresentationRequest(['presentation.html']);

// 2. Start the presentation (requires user gesture)
const startButton = document.getElementById('start-btn');

startButton.addEventListener('click', async () => {
  try {
    const connection = await request.start();
    console.log('Connected to presentation display!');

    // Handle connection events
    connection.addEventListener('terminate', () => {
      console.log('Connection terminated');
    });

    // Send a message to the receiver
    connection.send(JSON.stringify({ message: 'Hello from controller!' }));

  } catch (error) {
    console.error('Presentation failed:', error);
  }
});

Checking Availability

You can check if any displays are available before showing the button.

request.getAvailability().then((availability) => {
  console.log('Displays available:', availability.value);

  availability.addEventListener('change', () => {
    console.log('Availability changed:', availability.value);
  });
});

3. The Receiver (Presentation Page)

The page loaded on the secondary screen (presentation.html) accesses the navigator.presentation.receiver object to handle incoming connections.

// presentation.html script

if (navigator.presentation.receiver) {
  navigator.presentation.receiver.connectionList.then((list) => {

    // Handle existing connections
    list.connections.forEach(setupConnection);

    // Handle new connections
    list.addEventListener('connectionavailable', (event) => {
      setupConnection(event.connection);
    });
  });
}

function setupConnection(connection) {
  connection.addEventListener('message', (event) => {
    const data = JSON.parse(event.data);
    console.log('Received:', data.message);

    // Update UI on the big screen
    document.body.textContent = data.message;
  });

  // Send a response back
  connection.send('Hello from receiver!');
}

4. Communication

Communication happens via the PresentationConnection object, which behaves similarly to WebSockets.

  • send(data): Sends text, Blob, ArrayBuffer, or ArrayBufferView.
  • onmessage: Event fired when a message is received.
  • state: 'connecting', 'connected', 'closed', 'terminated'.

programming/javascript/vanilla/javascript programming/javascript/vanilla/events programming/javascript/vanilla/promises-async-await