Customize PWA Title Bars with Window Controls Overlay

The Window Controls Overlay (WCO) API enables Progressive Web Apps (PWAs) on desktop operating systems to provide an app-like experience by reclaiming the entire window surface, including the traditional title bar area. Instead of displaying a solid, browser-provided bar across the top of the app window, the browser overlays only the essential window control buttons (minimize, maximize/restore, and close) onto the web content. This allows developers to integrate custom navigation, search inputs, user profiles, and branding directly into the top region of their desktop web applications using standard Web App Manifest settings, CSS environment variables, and JavaScript APIs.

Enabling the Window Controls Overlay

To activate the feature, configure the Web App Manifest by adding "window-controls-overlay" to the display_override array. This informs the browser to hide the default title bar and overlay the operating system controls directly over your app’s content area when installed on desktop platforms.

{
  "name": "Desktop PWA",
  "display": "standalone",
  "display_override": ["window-controls-overlay"]
}

If the user’s browser or operating system does not support the API, the app gracefully falls back to the standard standalone mode title bar.

Positioning Elements with CSS

When Window Controls Overlay is active, the web layout extends behind the native control buttons. To avoid having content obscured by these buttons, CSS provides four predefined environment variables via the env() function:

These variables define the exact rectangle of the title bar that is safe for custom content. You can position a custom header element inside this area using standard CSS:

.custom-title-bar {
  position: fixed;
  left: env(titlebar-area-x, 0);
  top: env(titlebar-area-y, 0);
  width: env(titlebar-area-width, 100%);
  height: env(titlebar-area-height, 30px);
  display: flex;
  align-items: center;
  -webkit-app-region: drag;
  app-region: drag;
}

.custom-title-bar input,
.custom-title-bar button {
  -webkit-app-region: no-drag;
  app-region: no-drag;
}

The app-region: drag property allows users to move the window by clicking and dragging empty areas within your custom title bar. Interactive elements such as search inputs, buttons, and links must be explicitly styled with app-region: no-drag so they remain clickable.

Managing State and Geometry with JavaScript

The JavaScript API allows applications to react dynamically to changes in the title bar’s visibility and dimensions. The API is accessible via navigator.windowControlsOverlay.

Checking Feature Support and Visibility

You can verify whether the API is available and whether the overlay is currently visible:

if ('windowControlsOverlay' in navigator) {
  const isOverlayVisible = navigator.windowControlsOverlay.visible;
  console.log(`Overlay active: ${isOverlayVisible}`);
}

Accessing Bounding Coordinates

To get the exact pixel coordinates and dimensions of the available title bar space, use the getTitlebarAreaRect() method:

if ('windowControlsOverlay' in navigator) {
  const rect = navigator.windowControlsOverlay.getTitlebarAreaRect();
  console.log(`Title bar dimensions: ${rect.width}px by ${rect.height}px`);
  console.log(`Top-left offset: X=${rect.x}, Y=${rect.y}`);
}

Responding to Geometry Changes

When a user resizes the application window or changes screen displays, the geometry of the title bar area may update. Listen to the geometrychange event to adjust UI elements dynamically:

if ('windowControlsOverlay' in navigator) {
  navigator.windowControlsOverlay.addEventListener('geometrychange', (event) => {
    const { titlebarAreaRect, visible } = event;
    
    if (visible) {
      // Re-align or resize dynamic JavaScript components inside the custom bar
      console.log('New title bar width:', titlebarAreaRect.width);
    } else {
      // Reset layout when overlay is toggled off
      console.log('Window controls overlay hidden');
    }
  });
}

By combining the Web App Manifest configuration, CSS drag-region properties, and the navigator.windowControlsOverlay JavaScript interface, developers can seamlessly integrate app controls, navigation, and branding into the desktop title bar while preserving native platform behavior.