Browse the docs

settingsPane

Adds a settings pane with fields people fill in; the extension reads the values with ctx.settings.

Details #

Many extensions need a value only the person knows: a server name, a default project, an API key. The settingsPane point gives the extension a pane in its settings with a form for them. You describe the fields in the manifest. The app draws the form, checks the types and stores the values. Your code only reads them.

Unlike the other points, settingsPane is one object, not a list, and it has no code of its own. There is no builder for it. It needs an extension that reads the values, so the sample below adds a step that does.

It has a title and up to 50 fields. Each field has an id, a title, a type (string, number, boolean or secret) and optionally a default and a description.

{
  "adds": {
    "settingsPane": {
      "title": "Home Assistant",
      "fields": [
        { "id": "host", "title": "Host", "type": "string", "description": "Name or address on your network" },
        { "id": "token", "title": "Access token", "type": "secret" },
        { "id": "poll", "title": "Poll seconds", "type": "number", "default": 30 }
      ]
    }
  }
}

Gotchas #

  • The pane checks a value against the field's type when it is saved. A number field refuses text.

  • ctx.settings.get answers the field's default until the person sets a value. It is undefined if there is no default either.

  • Clearing a field puts the default back. An empty secret removes it.

  • Values are read each time you call get, so a change takes effect on the next run without a reload.

  • Secrets are never shown again in the form, only whether one is set. Do not put them in a normal string field, and do not log them.

  • A host a person types here is not known when you write the manifest. If the extension then talks to it on the local network, set permissions.network.lan to true.

A complete extension using this point can be downloaded from the Full example section and edited: a pane with a text field, a switch and a number, and a step that reads them.

Manifest fields #

FieldRequiredWhat it is
titleyesThe pane's heading.
fieldsyesUp to 50 fields, below.
fields[].idyesThe name you read the value by.
fields[].titleyesThe label in the form.
fields[].typeyesstring (text), number, boolean (a switch) or secret (a masked field kept in the Keychain).
fields[].defaultnoUsed until the person sets a value.
fields[].descriptionnoA line of help under the field.

Reading the values #

Read a value with ctx.settings.get(id). No permission is needed. A secret field is read with ctx.secrets.get(id) instead.

import { defineExtension, action } from '@switchboard/sdk';

export default defineExtension({
  actions: [
    action('ping', async (_p, ctx) => {
      const host = await ctx.settings.get<string>('host');
      const token = await ctx.secrets.get('token');
      return { host, hasToken: Boolean(token) };
    }),
  ],
});

Full example #

See also #