Skip to main content

Overview

The PluginSettingTab class allows you to create a dedicated settings tab for your plugin in Obsidian’s settings interface. It extends the SettingTab class and is automatically associated with your plugin instance. Since: 0.9.7

Constructor

constructor(app: App, plugin: Plugin)
app
App
required
Reference to the Obsidian app instance
plugin
Plugin
required
Reference to your plugin instance

Properties

app
App
Reference to the app instance
plugin
Plugin
Reference to your plugin instance
containerEl
HTMLElement
The HTML element that contains your settings UI. Add your settings controls to this element.
icon
IconName
The icon to display in the settings sidebar.Since: 1.11.0

Methods

display()

Called when the settings tab is opened. Override this method to build your settings UI.
abstract display(): void
This is an abstract method that you must implement in your subclass.

hide()

Called when the settings tab is closed. Use this to clean up any resources or unload components.
hide(): void
Any registered components should be unloaded when the view is hidden. Override this method if you need to perform additional cleanup beyond the default behavior.

Example

Basic Settings Tab

import { App, Plugin, PluginSettingTab, Setting } from 'obsidian';

interface MyPluginSettings {
    mySetting: string;
    enableFeature: boolean;
    apiKey: string;
}

const DEFAULT_SETTINGS: MyPluginSettings = {
    mySetting: 'default',
    enableFeature: true,
    apiKey: ''
}

export default class MyPlugin extends Plugin {
    settings: MyPluginSettings;

    async onload() {
        await this.loadSettings();

        // Add the settings tab
        this.addSettingTab(new MySettingTab(this.app, this));
    }

    async loadSettings() {
        this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData());
    }

    async saveSettings() {
        await this.saveData(this.settings);
    }
}

class MySettingTab extends PluginSettingTab {
    plugin: MyPlugin;

    constructor(app: App, plugin: MyPlugin) {
        super(app, plugin);
        this.plugin = plugin;
    }

    display(): void {
        const {containerEl} = this;

        containerEl.empty();

        // Add a heading
        containerEl.createEl('h2', {text: 'Settings for My Plugin'});

        // Text setting
        new Setting(containerEl)
            .setName('Setting name')
            .setDesc('Description of the setting')
            .addText(text => text
                .setPlaceholder('Enter your setting')
                .setValue(this.plugin.settings.mySetting)
                .onChange(async (value) => {
                    this.plugin.settings.mySetting = value;
                    await this.plugin.saveSettings();
                }));

        // Toggle setting
        new Setting(containerEl)
            .setName('Enable feature')
            .setDesc('Turn this feature on or off')
            .addToggle(toggle => toggle
                .setValue(this.plugin.settings.enableFeature)
                .onChange(async (value) => {
                    this.plugin.settings.enableFeature = value;
                    await this.plugin.saveSettings();
                }));

        // Password/secret setting
        new Setting(containerEl)
            .setName('API Key')
            .setDesc('Enter your API key')
            .addText(text => {
                text.setPlaceholder('API key')
                    .setValue(this.plugin.settings.apiKey)
                    .onChange(async (value) => {
                        this.plugin.settings.apiKey = value;
                        await this.plugin.saveSettings();
                    });
                text.inputEl.type = 'password';
            });
    }
}

Settings with Sections

class MySettingTab extends PluginSettingTab {
    display(): void {
        const {containerEl} = this;
        containerEl.empty();

        // General section
        containerEl.createEl('h2', {text: 'General Settings'});
        
        new Setting(containerEl)
            .setName('General setting 1')
            .addText(text => text
                .setValue(this.plugin.settings.general1)
                .onChange(async (value) => {
                    this.plugin.settings.general1 = value;
                    await this.plugin.saveSettings();
                }));

        // Advanced section
        containerEl.createEl('h2', {text: 'Advanced Settings'});
        containerEl.createEl('p', {
            text: 'These settings are for advanced users only.',
            cls: 'setting-item-description'
        });

        new Setting(containerEl)
            .setName('Advanced setting')
            .setDesc('Only change this if you know what you\'re doing')
            .addToggle(toggle => toggle
                .setValue(this.plugin.settings.advancedFeature)
                .onChange(async (value) => {
                    this.plugin.settings.advancedFeature = value;
                    await this.plugin.saveSettings();
                }));
    }
}

Dynamic Settings

class MySettingTab extends PluginSettingTab {
    display(): void {
        const {containerEl} = this;
        containerEl.empty();

        // Setting that controls visibility of other settings
        new Setting(containerEl)
            .setName('Enable advanced features')
            .addToggle(toggle => toggle
                .setValue(this.plugin.settings.enableAdvanced)
                .onChange(async (value) => {
                    this.plugin.settings.enableAdvanced = value;
                    await this.plugin.saveSettings();
                    // Refresh the display
                    this.display();
                }));

        // Show advanced settings only if enabled
        if (this.plugin.settings.enableAdvanced) {
            containerEl.createEl('h3', {text: 'Advanced Options'});
            
            new Setting(containerEl)
                .setName('Advanced option')
                .addText(text => text
                    .setValue(this.plugin.settings.advancedOption)
                    .onChange(async (value) => {
                        this.plugin.settings.advancedOption = value;
                        await this.plugin.saveSettings();
                    }));
        }
    }
}

Best Practices

Always Save Settings

Call saveSettings() in the onChange handler to persist changes immediately

Use Clear Labels

Provide descriptive names and descriptions for each setting

Group Related Settings

Use headings to organize settings into logical sections

Validate Input

Validate user input before saving to prevent invalid configurations
For complex settings UIs, consider using containerEl.createDiv() to create custom layouts beyond the default Setting component.

See Also

Build docs developers (and LLMs) love