What is Settings?
settings is the registry of settings screens. Register an entry and it becomes a real route in Discord’s settings navigation, listed under the Unbound section alongside the built-in General, Plugins, Design, and Developer pages.
It is a registry of screens, not of values. Persisting what those screens read and write is storage’s job.
Most plugins don’t need this module. A plugin that exports
getSettingsPanel already gets a settings button on its card in the Plugins list, and Unbound renders the returned node on a screen for you. Reach for registerSettings when you want a top-level entry of your own in the settings list, separate from your plugin’s card.Registering a screen
registerSettings takes one or more entries and adds them to the registry. Entries are keyed, so registering the same key twice overwrites the previous entry and logs a warning.
The entry shape
An entry mirrors Discord’sSETTING_RENDERER_CONFIG route shape, which is why it looks the way it does.
'route'
required
Always
'route'. Routes are the only entry kind Unbound registers.string
required
Unique identifier for the entry, and the key
removeSettings deletes by. Built-ins use screaming snake case (UNBOUND_GENERAL); namespace yours so it can’t collide.() => string
required
Hook returning the title shown in the list and the screen header. Being a hook, it can pull from i18n or from storage and re-render when either changes.
string | null
required
The key of the parent route, or
null for a top-level entry. Built-ins pass null.SettingsScreen
required
The screen this route renders.
string
The section label the entry is grouped under in the settings overview. Built-ins use
'Unbound'.() => boolean
Hook deciding whether the entry is shown. The built-in Developer page uses this to appear only while developer mode is on.
boolean
Hides the entry from the settings list while keeping the route navigable. Use it for screens you push to programmatically rather than ones the user picks from a list.
ComponentType<any>
Component rendered as the row’s leading icon. Built-ins render Discord’s
TableRowIcon with an id resolved through assets.Conditional and hidden entries
usePredicate is a hook, so it can subscribe to storage and hide or show the entry as settings change. This is how the Developer page appears only once developer mode is enabled.
Removing and inspecting
sections() returns only entries registered through this API. Unbound’s own built-in screens are merged in separately when the navigation config is read, so they don’t appear in the result.Settings vs storage
The two modules are complementary and it’s worth keeping them straight:
A settings screen almost always uses both:
settings puts the screen in the list, and storage holds what the controls on it read and write. Build the screen itself out of components, and see creating an addon for where the registration goes in a plugin’s lifecycle. Addon enabled-state is persisted by the managers, not by this module.