TitleBarStyle::Overlay in Tauri: How to Create Custom Window Chrome

TitleBarStyle::Overlay hides the native operating system title bar and overlays the webview content into that space, allowing developers to build fully custom title bars with HTML and CSS while preserving native window behaviors like dragging and traffic-light buttons.

The lencx/ChatGPT desktop application demonstrates how to leverage Tauri's titleBarStyle configuration to create a seamless, custom user interface. By setting titleBarStyle to Overlay in your Tauri configuration, you can replace the default system window chrome with your own React or Vue components without sacrificing native functionality.

What is TitleBarStyle::Overlay?

Tauri provides three distinct values for the titleBarStyle field in tauri.conf.json that control how the native window frame renders:

  • "Visible" — The default OS-provided title bar with standard window controls.
  • "Overlay" — The native title bar is hidden and the webview extends into that space, allowing custom HTML/CSS implementations while maintaining native drag behaviors and macOS traffic-light buttons.
  • "Transparent" (macOS only) — The title bar renders with a transparent background.

When you select "Overlay", Tauri removes the standard window decorations but keeps the underlying native window mechanisms active. This means double-click-to-maximize, window snapping, and platform-specific controls continue to function as expected, even though you are drawing the visual chrome yourself.

Configuring Overlay Mode in tauri.conf.json

To enable the overlay style, modify your src-tauri/tauri.conf.json file to disable standard decorations and set the title bar style. This configuration is essential for the custom implementation found in the lencx/ChatGPT repository.

{
  "tauri": {
    "windows": [
      {
        "title": "ChatGPT",
        "width": 1024,
        "height": 800,
        "decorations": false,
        "titleBarStyle": "Overlay",
        "transparent": false
      }
    ]
  }
}

Setting decorations to false removes the default OS window frame. Without this, the titleBarStyle: "Overlay" setting would conflict with the native chrome. The combination tells the Tauri runtime to create a borderless window where the webview fills the entire client area, including the region traditionally occupied by the title bar.

Implementing Draggable Custom Title Bars

Because the native title bar is hidden, you must explicitly designate which elements allow users to drag the window. Tauri provides the data-tauri-drag-region attribute for this purpose.

The data-tauri-drag-region Attribute

Any HTML element carrying this attribute (including its children) will respond to drag events as if it were the native title bar. In the lencx/ChatGPT application, the src/view/Titlebar.tsx component implements this pattern:

import { getCurrentWindow } from '@tauri-apps/api/window';
import { invoke } from '@tauri-apps/api/core';
import clsx from 'clsx';
import ThemeLight from '~icons/ThemeLight';
import ThemeDark from '~icons/ThemeDark';
import PinIcon from '~icons/Pin';
import UnPinIcon from '~icons/UnPin';

export default function Titlebar() {
  const win = getCurrentWindow();

  const toggleTheme = async () => {
    const next = (await win.theme()) === 'light' ? 'dark' : 'light';
    await invoke('set_theme', { theme: next });
  };

  return (
    <div
      data-tauri-drag-region
      className={clsx(
        'flex items-center h-10 px-2 bg-gray-100 dark:bg-gray-800',
        'select-none'
      )}
    >
      <div className="flex-1">
        <span className="ml-2 font-medium">ChatGPT</span>
      </div>

      <ThemeLight onClick={toggleTheme} className="mr-2 cursor-pointer" />
      <PinIcon onClick={() => invoke('window_pin', { pin: true })} />
      <UnPinIcon onClick={() => invoke('window_pin', { pin: false })} />
    </div>
  );
}

The data-tauri-drag-region attribute on the root div ensures users can click and drag anywhere on the custom bar to move the window. This is implemented in the Rust runtime via tauri::Builder, which processes these specific HTML data attributes to translate webview mouse events into native window drag operations.

Adding Window Controls and Native APIs

While the native traffic-light buttons remain available on macOS when using Overlay, you often need to implement custom controls for minimize, maximize, or close actions. The @tauri-apps/api/window package provides these capabilities programmatically.

import { appWindow } from '@tauri-apps/api/window';

async function closeApp() {
  await appWindow.close();
}

async function minimizeApp() {
  await appWindow.minimize();
}

async function toggleMaximize() {
  await appWindow.toggleMaximize();
}

In the lencx/ChatGPT implementation, these API calls connect to custom SVG icons in the React component. The getCurrentWindow() function returns the current WebviewWindow instance, allowing direct control over window state while the overlay bar provides the visual interface.

Key Implementation Files in lencx/ChatGPT

The repository contains several critical files that demonstrate this implementation pattern:

File Purpose Implementation Detail
src-tauri/tauri.conf.json Configuration Defines titleBarStyle: "Overlay" and decorations: false to activate overlay mode.
src/view/Titlebar.tsx Frontend Component React component using data-tauri-drag-region and @tauri-apps/api/window for custom controls.
src-tauri/src/main.rs Rust Entry Point Builds the Tauri application with tauri::Builder, respecting the overlay configuration.

These files work together to create a cohesive custom window experience where the Rust backend manages the native window lifecycle while the frontend handles the visual presentation and user interactions.

Summary

  • TitleBarStyle::Overlay removes the native OS title bar and extends the webview to fill that space, enabling fully custom UI implementations.
  • Configuration requires setting decorations: false alongside titleBarStyle: "Overlay" in tauri.conf.json.
  • The data-tauri-drag-region HTML attribute marks elements that should enable window dragging, replacing the native title bar's move behavior.
  • Use @tauri-apps/api/window to programmatically control window state (close, minimize, maximize) from your custom title bar components.
  • The lencx/ChatGPT repository demonstrates this pattern through src/view/Titlebar.tsx and corresponding Tauri configuration files.

Frequently Asked Questions

Does TitleBarStyle::Overlay work on all operating systems?

Yes, the Overlay style is supported on Windows, macOS, and Linux. However, platform-specific behaviors differ slightly. On macOS, the traffic-light buttons (close, minimize, maximize) remain visible and functional in the top-left corner even with decorations: false, while on Windows and Linux you must implement these controls entirely in HTML/CSS or enable decorations selectively.

How do I make my custom title bar draggable when using Overlay mode?

Add the data-tauri-drag-region attribute to the root element of your custom title bar component. This attribute signals the Tauri runtime to treat mouse events on that element as window drag operations. You can see this implementation in src/view/Titlebar.tsx within the lencx/ChatGPT repository, where the entire top bar allows window movement while containing interactive buttons.

Can I still use native window controls like minimize and maximize with Overlay?

Yes. While the visual chrome is hidden, the underlying native window still responds to platform conventions. You can programmatically trigger these actions using the @tauri-apps/api/window JavaScript API. Methods like appWindow.minimize(), appWindow.maximize(), and appWindow.close() allow your custom buttons to invoke native behaviors. On macOS specifically, the traffic-light buttons remain active in the overlay area unless explicitly disabled.

What is the difference between TitleBarStyle::Overlay and decorations: false?

Setting decorations: false alone removes the entire window frame, including the native drag region and traffic-light buttons, leaving you with a completely borderless window. Adding titleBarStyle: "Overlay" specifically tells Tauri to hide the title bar while preserving certain native behaviors like the drag region (via data-tauri-drag-region) and macOS window controls. The overlay style is designed for custom title bars, while decorations: false is typically used for fullscreen or kiosk-style applications.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →