Skip to content

Overlay

Joël Deffner edited this page Sep 3, 2026 · 1 revision

Overlay

Since v0.5.0. steam.overlay is the curated layer over the Steam overlay: open its dialogs, place its notifications, and know when it is up. The calls come from two interfaces, ISteamFriends for the dialogs and ISteamUtils for the notification placement, which is why it is called overlay rather than after either one: the generated classes already own steam.friends and steam.utils.

Every activate method is fire and forget. Steam has no result for them, so a bad dialog name or a disabled overlay does nothing and reports nothing. Check isEnabled first when that matters.

The overlay draws into the game's own renderer. Node has none, so a plain Node or Electron process gets no overlay from this package: the calls are accepted and nothing appears. This layer is for a game that already renders through a hookable API. onActivated is where such a game pauses itself, because the overlay takes input focus while it is open.

The Overlay instance is created lazily and cached on the Steam object. The friend and presence half of ISteamFriends is on Social.

isEnabled

isEnabled(): boolean

Whether the overlay is loaded and ready. False until it has hooked the process, which takes a moment after startup, and permanently false when the user turned it off or the app runs outside Steam. This is the only honest way to tell whether the activate calls will do anything.

import { init } from 'steamwand.js';

const steam = init({ appId: 480 });
if (steam.overlay.isEnabled()) steam.overlay.activate('Friends');
steam.close();

activate

activate(dialog: OverlayDialog): void

Opens a top level overlay dialog: Friends, Community, Players, Settings, OfficialGameGroup, Stats or Achievements. Any other string is passed through unchanged, so a dialog Valve adds later still works.

activateToUser

activateToUser(dialog: OverlayUserDialog, steamId: bigint): void

Opens a dialog about one user, clan or lobby. dialog is steamid for the profile, chat to start a conversation, or one of jointrade, stats, achievements, friendadd, friendremove, friendrequestaccept, friendrequestignore. Unknown strings pass through unchanged.

const [friend] = steam.social.listFriends();
if (friend) steam.overlay.activateToUser('steamid', friend.steamId);

activateToWebPage

activateToWebPage(url: string, modal?: boolean): void

Opens a web page in the overlay browser. url needs the protocol. modal (default false) opens a stripped browser window the user must close before returning to the game.

activateToStore

activateToStore(appId: number, flag?: number): void

Opens a store page in the overlay. flag is an EOverlayToStoreFlag: 0 just show the page (the default), 1 add to cart, 2 add to cart and show the cart. Pass appId 0 with a cart flag to show the cart itself.

activateInviteDialog

activateInviteDialog(lobbyId: bigint): void

Opens the invite dialog for a lobby, so the user can pick friends to invite. The user must already be in that lobby. Invitees who accept get a GameLobbyJoinRequested_t, which social.onGameLobbyJoinRequested delivers.

import { init, flat } from 'steamwand.js';

const steam = init({ appId: 480 });
const lobbyId = await steam.lobbies.create(flat.ELobbyType.k_ELobbyTypeFriendsOnly, 4);
steam.overlay.activateInviteDialog(lobbyId);

activateInviteDialogConnectString

activateInviteDialogConnectString(connect: string): void

The same dialog for a game with no lobby, using a plain connect string of at most 256 UTF-8 bytes: whatever your game needs to join, for example a server address. Invitees get the string back through social.onGameRichPresenceJoinRequested when the app is running, or as +connect <string> on the command line when it is not.

setNotificationPosition

setNotificationPosition(position?: number): void

Moves the overlay notifications (achievement popups, chat toasts) to one corner of the screen. position is an ENotificationPosition: 0 top left, 1 top right, 2 bottom left, 3 bottom right, which is the default.

import { init, flat } from 'steamwand.js';

const steam = init({ appId: 480 });
steam.overlay.setNotificationPosition(flat.ENotificationPosition.k_EPositionTopLeft);
steam.overlay.setNotificationInset(16, 48);
steam.close();

setNotificationInset

setNotificationInset(x: number, y: number): void

Pushes the notifications away from the edges of their corner, in pixels, to keep them clear of your own HUD. The inset applies to the corner setNotificationPosition chose, so set the position first.

onActivated

onActivated(listener: (event: OverlayActivation) => void): () => void

Subscribes to the overlay opening and closing, and returns an unsubscribe function. event.active is true when it just opened. This is where a single player game pauses itself.

const off = steam.overlay.onActivated((e) => {
  console.log(e.active ? 'paused' : 'resumed');
});
// later: off();

Types

OverlayDialog

The documented top level dialog names, as a union with (string & {}) so any other string is still accepted:

'Friends' | 'Community' | 'Players' | 'Settings' | 'OfficialGameGroup' | 'Stats' | 'Achievements'

OverlayUserDialog

The documented per-user dialog names, same open union:

'steamid' | 'chat' | 'jointrade' | 'stats' | 'achievements' | 'friendadd' | 'friendremove' | 'friendrequestaccept' | 'friendrequestignore'

OverlayActivation

Handed to an onActivated listener.

Field Type Meaning
active boolean True when the overlay just opened, false when it just closed.

Errors

None. Every method here either returns a boolean read or calls a Steam function with no result, so this layer throws nothing at all: no SteamResultError, no plain Error. A call that did nothing looks exactly like a call that worked, which is what isEnabled is for.

What this layer does not do

The overlay calls this layer skips are on the raw generated interfaces:

  • ActivateGameOverlayRemotePlayTogetherInviteDialog, the Remote Play Together variant of the invite dialog, on steam.friends.
  • RegisterProtocolInOverlayBrowser, which lets the overlay browser open a custom URL scheme, also on steam.friends.
  • InviteUserToGame, which sends one named friend a connect string without opening a dialog.
  • BOverlayNeedsPresent, on steam.utils, which a renderer polls to know it must present a frame for the overlay to draw over.

Flat API explains the calling convention.

Next: Social for the friend list and rich presence that feed these dialogs.

Clone this wiki locally