Skip to content

Steam Overlay

Control the Steam overlay. Works on macOS, Windows, and Linux.

Cross-Platform Support

GemShell automatically handles Steam overlay compatibility on all platforms. No additional setup required.

Methods

isOverlayEnabled()

Check if overlay is available (enabled in Steam settings).

javascript
const enabled = await steam.isOverlayEnabled();

isShowing()

Check if the overlay is currently visible (user pressed Shift+Tab).

javascript
const showing = await gemshell.overlay.isShowing();

if (showing) {
  // Pause game while overlay is open
}

onStateChange(callback)

Listen for overlay state changes. Useful for pausing your game when the player opens the overlay.

javascript
gemshell.overlay.onStateChange((isShowing) => {
  if (isShowing) {
    pauseGame();
    console.log('Overlay opened');
  } else {
    resumeGame();
    console.log('Overlay closed');
  }
});

activateOverlay(dialog)

Open overlay to a specific dialog.

javascript
await steam.activateOverlay('achievements');

Dialog Options (Steam expects these lowercase):

  • 'friends' - Friends list
  • 'community' - Community hub
  • 'players' - Recent players
  • 'settings' - Steam settings
  • 'officialgamegroup' - Game's Steam group
  • 'stats' - Stats page
  • 'achievements' - Achievements

Returns: false if the dialog name isn't one of the above.

Capitalised names used to open the wrong dialog

Steam silently falls back to its default view — the friends list — for any dialog name it doesn't recognise, and it only recognises lowercase. Earlier versions of this page showed 'Friends', 'Achievements' etc., so those calls all opened the friends list regardless of which one you asked for. GemShell now lowercases the name for you, so both spellings work, and an unknown name returns false instead of opening something unexpected.

activateOverlayToWebPage(url)

Open overlay browser to URL.

javascript
await steam.activateOverlayToWebPage('https://mygame.com/help');

triggerScreenshot()

Take a Steam screenshot.

javascript
await steam.triggerScreenshot();

Examples

Auto-Pause on Overlay

javascript
// Automatically pause when player opens Steam overlay
gemshell.overlay.onStateChange((isShowing) => {
  if (isShowing) {
    game.pause();
    audio.mute();
  } else {
    game.resume();
    audio.unmute();
  }
});

Open Friends

javascript
async function openFriends() {
  if (await steam.isOverlayEnabled()) {
    await steam.activateOverlay('friends');
  }
}

Open Help Page

javascript
async function openHelp() {
  await steam.activateOverlayToWebPage('https://mygame.com/wiki');
}

Screenshot Button

javascript
document.addEventListener('keydown', async (e) => {
  if (e.key === 'F12') {
    await steam.triggerScreenshot();
  }
});

Overlay Menu

javascript
const overlayOptions = [
  { label: 'Friends', action: () => steam.activateOverlay('friends') },
  { label: 'Achievements', action: () => steam.activateOverlay('achievements') },
  { label: 'Community', action: () => steam.activateOverlay('community') },
  { label: 'Wiki', action: () => steam.activateOverlayToWebPage('https://mygame.com/wiki') }
];

function showOverlayMenu() {
  // Show menu with options
}

Platform Notes

Requirements

Steam Overlay requires specific conditions to work:

  • Game must be launched through Steam
  • Overlay must be enabled in Steam settings
  • Game must have a valid Steam App ID configured

Checking Availability

Always check before using overlay features:

javascript
async function safeActivateOverlay(dialog) {
  if (await steam.isOverlayEnabled()) {
    await steam.activateOverlay(dialog);
    return true;
  }
  return false;
}

Fallback for Web

javascript
async function openHelp() {
  const hasOverlay = await steam.isOverlayEnabled();
  
  if (hasOverlay) {
    await steam.activateOverlayToWebPage('https://mygame.com/help');
  } else {
    // Fallback: open in default browser
    await gemshell.os.openURL('https://mygame.com/help');
  }
}

Overlay State API

The overlay state API allows you to detect when the Steam overlay is open.

gemshell.overlay

MethodReturnsDescription
isAvailable()Promise<boolean>Check if overlay injection was successful
isInjected()Promise<boolean>Check if OpenGL/WGL layer is injected
isShowing()Promise<boolean>Check if overlay is currently visible
onStateChange(callback)voidListen for overlay open/close events

Example: Game Pause System

javascript
class GamePauseManager {
  constructor() {
    this.isPaused = false;
    this.setupOverlayListener();
  }
  
  setupOverlayListener() {
    gemshell.overlay.onStateChange((overlayOpen) => {
      if (overlayOpen && !this.isPaused) {
        this.pause('overlay');
      } else if (!overlayOpen && this.pauseReason === 'overlay') {
        this.resume();
      }
    });
  }
  
  pause(reason) {
    this.isPaused = true;
    this.pauseReason = reason;
    // Stop game loop, mute audio, etc.
  }
  
  resume() {
    this.isPaused = false;
    this.pauseReason = null;
    // Resume game loop, unmute audio, etc.
  }
}