Experimental: This is an experimental technology
Check the Browser compatibility table carefully before using this in production.

The Clients interface provides access to Client (en-US) objects. Access it via self.clients within a service worker (en-US).


Clients.get() (en-US)

Returns a Promise for a Client (en-US) matching a given id (en-US).

Clients.matchAll() (en-US)

Returns a Promise for an array of Client (en-US) objects. An options argument allows you to control the types of clients returned.

Clients.openWindow() (en-US)

Opens a new browser window for a given url and returns a Promise for the new WindowClient (en-US).


Allows an active service worker to set itself as the controller (en-US) for all clients within its scope (en-US).


The following example shows an existing chat window or creates a new one when the user clicks a notification.

addEventListener('notificationclick', event => {
  event.waitUntil(async function() {
    const allClients = await clients.matchAll({
      includeUncontrolled: true

    let chatClient;

    // Let's see if we already have a chat window open:
    for (const client of allClients) {
      const url = new URL(client.url);

      if (url.pathname == '/chat/') {
        // Excellent, let's use it!
        chatClient = client;

    // If we didn't find an existing chat window,
    // open a new one:
    if (!chatClient) {
      chatClient = await clients.openWindow('/chat/');

    // Message the client:
    chatClient.postMessage("New chat messages!");


Service Workers
# clients-interface

브라우저 호환성

BCD tables only load in the browser

See also