Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/betterdiscord/betterdiscord/llms.txt

Use this file to discover all available pages before exploring further.

BetterDiscord provides a comprehensive settings system with pre-built React components for common input types.

Basic settings panel

Implement getSettingsPanel() in your plugin to return a settings UI:
getSettingsPanel() {
    return BdApi.UI.buildSettingsPanel({
        settings: [
            {
                type: "switch",
                id: "enabled",
                name: "Enable Feature",
                note: "Toggle the main feature on or off",
                value: this.settings.enabled,
                onChange: (value) => {
                    this.settings.enabled = value;
                    this.saveSettings();
                }
            }
        ]
    });
}

Setting types

BetterDiscord supports multiple setting component types:

Switch

Boolean toggle switch:
{
    type: "switch",
    id: "enableNotifications",
    name: "Enable Notifications",
    note: "Show notifications when events occur",
    value: this.settings.enableNotifications,
    onChange: (value) => {
        this.settings.enableNotifications = value;
        this.saveSettings();
    }
}

Text input

Single-line text input:
{
    type: "text",
    id: "username",
    name: "Username",
    note: "Enter your username",
    value: this.settings.username,
    placeholder: "Enter username...",
    onChange: (value) => {
        this.settings.username = value;
        this.saveSettings();
    }
}

Number input

Numeric input with optional min/max:
{
    type: "number",
    id: "maxItems",
    name: "Maximum Items",
    note: "Maximum number of items to display",
    value: this.settings.maxItems,
    min: 1,
    max: 100,
    onChange: (value) => {
        this.settings.maxItems = value;
        this.saveSettings();
    }
}

Slider

Range slider with visual feedback:
{
    type: "slider",
    id: "volume",
    name: "Volume",
    note: "Adjust the volume level",
    value: this.settings.volume,
    min: 0,
    max: 100,
    step: 5,
    units: "%",
    markers: [0, 25, 50, 75, 100],
    onChange: (value) => {
        this.settings.volume = value;
        this.saveSettings();
    }
}
markers
array
Array of numbers or marker objects: {value: number, label: string}
Select from a list of options:
{
    type: "dropdown",
    id: "theme",
    name: "Theme",
    note: "Choose your preferred theme",
    value: this.settings.theme,
    options: [
        {label: "Light", value: "light"},
        {label: "Dark", value: "dark"},
        {label: "Auto", value: "auto"}
    ],
    onChange: (value) => {
        this.settings.theme = value;
        this.saveSettings();
    }
}

Radio buttons

Exclusive selection with descriptions:
{
    type: "radio",
    id: "displayMode",
    name: "Display Mode",
    note: "Choose how to display content",
    value: this.settings.displayMode,
    options: [
        {
            name: "Compact",
            value: "compact",
            description: "Show minimal information"
        },
        {
            name: "Cozy",
            value: "cozy",
            description: "Balanced view"
        },
        {
            name: "Expanded",
            value: "expanded",
            description: "Show all details",
            color: "#5865F2"
        }
    ],
    onChange: (value) => {
        this.settings.displayMode = value;
        this.saveSettings();
    }
}

Color picker

Color selection with swatches:
{
    type: "color",
    id: "accentColor",
    name: "Accent Color",
    note: "Choose your accent color",
    value: this.settings.accentColor,
    defaultValue: "#5865F2",
    onChange: (value) => {
        this.settings.accentColor = value;
        this.saveSettings();
    }
}
Value can be a hex string ("#5865F2") or integer (5793522).

Keybind

Keyboard shortcut recorder:
{
    type: "keybind",
    id: "toggleShortcut",
    name: "Toggle Shortcut",
    note: "Press keys to set shortcut",
    value: this.settings.toggleShortcut,
    max: 3,
    clearable: true,
    onChange: (value) => {
        this.settings.toggleShortcut = value;
        this.saveSettings();
    }
}
Value is an array of key names: ["Control", "Shift", "K"]

Organizing settings

Group related settings using categories:
getSettingsPanel() {
    return BdApi.UI.buildSettingsPanel({
        settings: [
            {
                type: "category",
                id: "appearance",
                name: "Appearance",
                collapsible: true,
                shown: true,
                settings: [
                    {
                        type: "color",
                        id: "accentColor",
                        name: "Accent Color",
                        value: this.settings.accentColor,
                        onChange: (value) => this.updateSetting("accentColor", value)
                    },
                    {
                        type: "slider",
                        id: "opacity",
                        name: "Opacity",
                        value: this.settings.opacity,
                        min: 0,
                        max: 100,
                        onChange: (value) => this.updateSetting("opacity", value)
                    }
                ]
            },
            {
                type: "category",
                id: "behavior",
                name: "Behavior",
                collapsible: true,
                shown: false,
                settings: [
                    {
                        type: "switch",
                        id: "autoStart",
                        name: "Auto Start",
                        value: this.settings.autoStart,
                        onChange: (value) => this.updateSetting("autoStart", value)
                    }
                ]
            }
        ],
        onChange: (category, id, value) => {
            this.api.Logger.info(`Setting changed: ${category}/${id} = ${value}`);
        }
    });
}

Persisting settings

Save and load settings using BdApi.Data:
module.exports = class MyPlugin {
    constructor() {
        this.api = new BdApi("MyPlugin");
        this.defaultSettings = {
            enabled: true,
            theme: "dark",
            volume: 50
        };
    }
    
    start() {
        this.loadSettings();
    }
    
    loadSettings() {
        this.settings = this.api.Data.load("settings");
        
        // Merge with defaults for any missing keys
        if (!this.settings) {
            this.settings = {...this.defaultSettings};
        } else {
            this.settings = {...this.defaultSettings, ...this.settings};
        }
    }
    
    saveSettings() {
        this.api.Data.save("settings", this.settings);
    }
    
    updateSetting(key, value) {
        this.settings[key] = value;
        this.saveSettings();
        
        // Apply setting immediately
        this.applySetting(key, value);
    }
    
    applySetting(key, value) {
        switch(key) {
            case "theme":
                this.applyTheme(value);
                break;
            case "volume":
                this.setVolume(value);
                break;
        }
    }
};

Advanced: Custom components

For complex settings, use custom React components:
getSettingsPanel() {
    const {React} = BdApi;
    
    const CustomSetting = () => {
        const [value, setValue] = React.useState(this.settings.custom);
        
        return React.createElement("div", {className: "custom-setting"},
            React.createElement("h3", {}, "Custom Setting"),
            React.createElement("input", {
                type: "range",
                min: 0,
                max: 100,
                value: value,
                onChange: (e) => {
                    setValue(e.target.value);
                    this.updateSetting("custom", e.target.value);
                }
            }),
            React.createElement("span", {}, value)
        );
    };
    
    return BdApi.UI.buildSettingsPanel({
        settings: [
            {
                type: "custom",
                id: "customSetting",
                name: "Advanced Setting",
                note: "This is a custom component",
                children: React.createElement(CustomSetting)
            }
        ]
    });
}

Using BdApi.Components

Access individual setting components directly:
getSettingsPanel() {
    const {React, Components} = BdApi;
    const {SettingItem, SwitchInput, SliderInput, SettingGroup} = Components;
    
    return React.createElement(SettingGroup, {},
        React.createElement(SettingItem, {
            id: "enable-feature",
            name: "Enable Feature",
            note: "Toggle this feature"
        },
            React.createElement(SwitchInput, {
                value: this.settings.enabled,
                onChange: (value) => this.updateSetting("enabled", value)
            })
        ),
        React.createElement(SettingItem, {
            id: "volume",
            name: "Volume",
            note: "Adjust volume level"
        },
            React.createElement(SliderInput, {
                value: this.settings.volume,
                min: 0,
                max: 100,
                units: "%",
                onChange: (value) => this.updateSetting("volume", value)
            })
        )
    );
}

Component props reference

All setting components accept these common props:
value
any
required
Current value of the setting
onChange
function
Callback when value changes: (newValue) => void
disabled
boolean
Whether the input is disabled (default: false)
See the type definitions in the source for component-specific props:
  • SwitchInput: ~/workspace/source/src/betterdiscord/ui/settings/components/switch.tsx:7-13
  • SliderInput: ~/workspace/source/src/betterdiscord/ui/settings/components/slider.tsx:13-22
  • TextInput: ~/workspace/source/src/betterdiscord/ui/settings/components/textbox.tsx:8-15
  • DropdownInput: ~/workspace/source/src/betterdiscord/ui/settings/components/dropdown.tsx:9-21
  • RadioInput: ~/workspace/source/src/betterdiscord/ui/settings/components/radio.tsx:18-24
  • ColorInput: ~/workspace/source/src/betterdiscord/ui/settings/components/color.tsx:50-56
  • KeybindInput: ~/workspace/source/src/betterdiscord/ui/settings/components/keybind.tsx:11-17