Upgrading to Version 3.x
Within this article, you'll learn what's new in @elgato/streamdeck version 3 and how to upgrade.
Updating
Install the latest versions of the SDK and CLI.
npm i @elgato/streamdeck@latest @elgato/cli@latestUpdate your plugin to require Stream Deck 7.1 or higher.
{
"Software": {
"MinimumVersion": "7.1"
}
}Changes
- Neo Infobar actions are now available!
- Settings events now only fire when settings are changed in the property inspector.
- Action settings are now bound to the settings type defined on the
SingletonAction. - Action type is now a union of key, dial, and Neo Infobar actions.
- Secrets API has been removed.
What's New
Neo Infobar Actions
Neo Infobar actions are now available for Stream Deck Neo! They provide a dedicated, non-interactive space where plugins can display information at a glance. These actions use the same layout engine as Stream Deck + and Stream Deck + XL, so they will be familiar to Makers who have built dial actions.
Learn more about Neo Infobar actions in the new documentation page.
Neo Infobar actions require Stream Deck 7.6 or later—be sure to update your manifest's Software.MinimumVersion when adding support for them.
To get started with Neo Infobar actions, add or update an action to the manifest, specifying the Neo controller.
{
"Actions": [
{
"Name": "Neo Infobar Example Action",
"UUID": "com.elgato.example.neo-infobar",
"Controllers": ["Neo"]
}
]
}Within your action's implementation, you can then access Neo Infobar methods by checking the action type using isNeoInfobar().
import { action, SingletonAction, WillAppearEvent } from "@elgato/streamdeck";
@action({ UUID: "com.elgato.example.neo-infobar" })
export class ExampleNeoInfobarAction extends SingletonAction {
/**
* Occurs when the action appears.
*/
override async onWillAppear(ev: WillAppearEvent): Promise<void> {
if (ev.action.isNeoInfobar()) {
// Set the layout.
await ev.action.setFeedbackLayout("layout.json");
await ev.action.setFeedback({
img: "logo",
text: "Hello world",
});
}
}
}Settings Events Lifecycle
onDidReceiveSettings and onDidReceiveGlobalSettings now only fire when settings are changed in the property inspector. Calling getSettings or getGlobalSettings no longer causes these events to fire.
- Before
- Now
streamDeck.settings.onDidReceiveGlobalSettings((ev) => {
// Fired when the settings change in the property inspector
// and when getting the settings.
});
const settings = await streamDeck.settings.getGlobalSettings();streamDeck.settings.onDidReceiveGlobalSettings((ev) => {
// Fired when the settings change in the property inspector.
});
const settings = await streamDeck.settings.getGlobalSettings();The improved settings events lifecycle is enabled through message identifiers, introduced in Stream Deck 7.1—plugins will therefore need to target Stream Deck 7.1 or higher in their manifest (learn more).
Should your plugin require an older version of Stream Deck, you can temporarily retain the previous behavior by setting useLegacySettingsBehavior to true before connecting:
streamDeck.settings.useLegacySettingsBehavior = true;
await streamDeck.connect();The new settings events behavior was previously available in version 2.x by enabling useExperimentalMessageIdentifiers—this option has now been removed.
What's Changed
Action Settings
getSettings and setSettings now use the settings type defined on the SingletonAction. Their method-level generic type has been removed, preventing settings from being read or written using a type that differs from the action's settings.
- Before
- Now
export class SampleAction extends SingletonAction<Settings> {
override async onKeyDown(ev: KeyDownEvent<Settings>): Promise<void> {
// No error, `SomeOtherSettings` type differs from `Settings`
await ev.action.getSettings<SomeOtherSettings>();
}
}export class SampleAction extends SingletonAction<Settings> {
override async onKeyDown(ev: KeyDownEvent<Settings>): Promise<void> {
// Get settings return type is `Settings`
await ev.action.getSettings();
}
}Action Type
The Action type is now a union of KeyAction, DialAction, and NeoInfobarAction, rather than the base class shared by key and dial actions. With the introduction of Neo Infobar actions, type narrowing using isKey(), isDial(), and isNeoInfobar() may be required before calling methods, such as setTitle.
- Before
- Now
export class SampleAction extends SingletonAction {
override async onWillAppear(ev: WillAppearEvent): Promise<void> {
// Action is key or dial
// Both keys and dials support setTitle
await ev.action.setTitle("Ready");
}
}export class SampleAction extends SingletonAction {
override async onWillAppear(ev: WillAppearEvent): Promise<void> {
// Action is key, dial, or Neo Infobar
// Neo Infobar does not support setTitle, so narrowing is required
if (ev.action.isKey() || ev.action.isDial()) {
await ev.action.setTitle("Ready");
}
}
}Additionally, when referencing the Action, KeyAction, DialAction, or NeoInfobarAction type, its associated settings type must always be specified.
- Before
- Now
import type { KeyAction } from "@elgato/streamdeck";
const action: KeyAction; import type { KeyAction } from "@elgato/streamdeck";
type Settings = {
count: number;
};
const action: KeyAction<Settings>; Secrets
The streamDeck.system.getSecrets API and all of its associated types have been removed.