Skip to main content
Settings allow your plugin to be configured by pilots (user-scoped) or by the VA admin platform (airline-scoped). They’re declared in plugin.json and the shell renders a settings UI for pilots automatically — no settings page required in your plugin.

Declaring Settings

Add an availableSettings array to your plugin.json:
{
  "availableSettings": [
    {
      "key": "welcome_message",
      "name": "Welcome Message",
      "description": "Custom message displayed on the dashboard",
      "type": "longtext",
      "scope": "airline",
      "placeholder": "Enter a welcome message..."
    },
    {
      "key": "show_map",
      "name": "Show Map",
      "description": "Display the flight map on the main page",
      "type": "boolean",
      "scope": "user",
      "default": true
    },
    {
      "key": "units",
      "name": "Unit System",
      "type": "list",
      "scope": "user",
      "default": "imperial",
      "options": [
        { "value": "imperial", "label": "Imperial (ft, kts, lbs)" },
        { "value": "metric", "label": "Metric (m, km/h, kg)" }
      ]
    },
    {
      "key": "refresh_interval",
      "name": "Refresh Interval",
      "description": "How often to refresh data (seconds)",
      "type": "range",
      "scope": "user",
      "default": 30,
      "min": 5,
      "max": 120,
      "step": 5
    }
  ]
}

Setting Types

TypeRendered AsExtra Fields
booleanToggle switchdefault?: boolean
textText inputdefault?, pattern?, placeholder?
longtextTextareadefault?, placeholder?
numberNumber inputdefault?, min?, max?, step?
rangeSliderdefault?, min (required), max (required), step?
listDropdown selectdefault?, options (required)
radioRadio groupdefault?, options (required)
dateDate pickerdefault?
jsonMonospace textareadefault?
For list and radio types, options is an array of { value: string; label: string } objects.

Setting Scopes

"user" scope

Appears in the Stratos Settings page under your plugin’s section. Each pilot can configure their own value independently. Use user-scoped settings for:
  • Unit system preferences (imperial vs metric)
  • Display toggles (show/hide sections)
  • Notification preferences
  • Refresh intervals

"airline" scope

Managed by the VA admin platform and pushed to all pilots. Read-only in the client. The shell fetches airline-scoped values from the platform when the pilot authenticates. Use airline-scoped settings for:
  • Welcome messages and branding
  • Quick links and resources
  • Event detection rules
  • Route configurations
  • Any content the VA wants to control centrally
Airline-scoped settings can be updated from the Skyvex platform without rebuilding or redeploying the plugin.

Reading Settings in the UI

Use usePluginContext() to access settings from any component:
import { usePluginContext } from "@skyvexsoftware/stratos-sdk";

function MyComponent() {
  const ctx = usePluginContext();

  const welcomeMsg = ctx.config.get<string>("welcome_message", "Hello!");
  const showMap = ctx.config.get<boolean>("show_map", true);
  const units = ctx.config.get<string>("units", "imperial");
  const interval = ctx.config.get<number>("refresh_interval", 30);

  return (
    <div className="p-6">
      <p className="text-lg">{welcomeMsg}</p>
      {showMap && <MapView />}
    </div>
  );
}
Or with the useShellConfig() hook directly:
import { useShellConfig } from "@skyvexsoftware/stratos-sdk";

function MyComponent() {
  const config = useShellConfig();
  const showMap = config.get<boolean>("show_map", true);
}
UI config access is synchronous — values are available immediately on render.

Reading Settings in a Background Module

Background config access uses ctx.config and is async:
import type { PluginContext } from "@skyvexsoftware/stratos-sdk";

export async function onStart(ctx: PluginContext): Promise<void> {
  const interval = await ctx.config.get<number>("refresh_interval", 30);
  const links = await ctx.config.get<object[]>("quick_links", []);

  ctx.logger.info("Init", `Starting with interval=${interval}s`);
}

Always Provide Defaults

Your plugin should work out of the box without any settings configured. The second argument to config.get is the fallback value returned when the setting has not been set:
// Falls back to 30 if never configured
const interval = ctx.config.get<number>("refresh_interval", 30);

// Falls back to true if never configured
const showMap = ctx.config.get<boolean>("show_map", true);

// Falls back to empty array
const links = ctx.config.get<QuickLink[]>("quick_links", []);
Never assume a setting has a value — always pass a sensible default.