Settings, storage, and files
Reference for dd.settings, dd.storage and its limits, dd.files, and how secret references resolve.
dd.settings
Reading settings needs no permission. Fields are declared in the manifest (see the manifest reference); values are edited by the user in the shell's settings dialog, never written by the widget.
dd.settings.get()
dd.settings.get(): Promise<Record<string, unknown>>The effective settings: manifest defaults merged with the user's stored values. Always returns the persisted state, even while the settings dialog previews something else.
dd.settings.onChange()
dd.settings.onChange(cb: (settings: Record<string, unknown>) => void): () => voidFires on any settings edit. While the user tries values in the settings dialog it also fires with live-previewed (unsaved) values, and fires once more with the stored values if they dismiss. Treat every event the same and just re-apply; do not try to distinguish preview from commit.
dd.settings.bind()
dd.settings.bind(cb: (settings: Record<string, unknown>) => void): Promise<() => void>Load-and-listen in one call: cb fires once with the current settings and
again on every change. The returned promise resolves (with the unsubscribe
function) after that first call, so await dd.settings.bind(cb) when the
code below needs settings populated.
dd.storage
Needs the storage permission. A small per-instance key-value store,
persisted by the host; two instances of the same widget do not share it.
dd.storage.get(key: string): Promise<unknown> // stored value or null
dd.storage.set(key: string, value: unknown): Promise<void>
dd.storage.delete(key: string): Promise<void>Limits: a value is capped at 64 KB serialized, the whole store at 512 KB per
instance. Exceeding either rejects PAYLOAD_TOO_LARGE. This is state
storage, not a database; keep large data out of it.
dd.files
Needs the files permission.
dd.files.read()
dd.files.read(settingKey: string): Promise<{
text: string;
sizeBytes: number;
modifiedEpochMs?: number;
}>Reads the file the user configured in the named filePath setting of this
widget. Widgets never handle raw paths: you name your own setting key, the
host resolves the path the user granted there. Manifest defaults for
filePath fields are deliberately ignored, so there is no way to ship a
widget pre-pointed at someone's file. Files are capped at 1 MB.
How secrets work
A secretRef setting names a secret stored by the host; the user picks which
one in the settings dialog, and the secret's value never reaches widget code.
The only place a widget can use one is dd.http.fetch: pass
{ "$secret": "settingKey" } as a header or query value and the host injects
the real value after validating the request. See
dd.http.fetch for the exact
rules. There is no API that returns a secret's value.