Xgenious/ docs
Products
Get support

Dashboard Menus

Plugins can inject menu items into the admin sidebar. The sidebar renders all registered menus automatically — no Blade code needed.

add_menu() Config Keys

KeyTypeRequiredDescription
idstringRequiredUnique identifier, used as parent ID for submenus.
labelstringRequiredDisplayed menu text. Wrap in __() for translations.
iconstringRequiredMDI icon class, e.g. mdi-cart. See pictogrammers.com.
routestringRequiredNamed Laravel route to link to.
orderintOptionalSort order in sidebar. Lower = higher. Default 50.
contextenumOptionallandlord, tenant, or both. Defaults to plugin type.
permissionstringOptionalGate permission string required to see this menu item.
$this->add_menu([
    'id'         => 'acme-loyalty-menu',
    'label'      => __('Loyalty Points'),
    'icon'       => 'mdi-star',
    'route'      => 'tenant.admin.acme.loyalty.index',
    'order'      => 80,
    'context'    => 'tenant',
    'permission' => 'manage-loyalty',
]);

$this->add_submenu('acme-loyalty-menu', [
    'id'    => 'acme-loyalty-settings',
    'label' => __('Settings'),
    'icon'  => 'mdi-cog',
    'route' => 'tenant.admin.acme.loyalty.settings',
]);

Plugin Settings API

Call register_settings() to declare your plugin's options. The platform auto-generates a styled settings page with validation — no controller needed.

Warning

⚠️ Call register_settings() in routes(), not only in boot(). The plugin card's Settings button is powered by SettingsManager::hasDefinitions(), which only returns true after register_settings() has been called. Because routes() runs for every discovered plugin (active or inactive), putting the call there guarantees the button appears regardless of active state or tenant context. Call it in boot() as well (it is idempotent) so settings are available when hooks and menus run.

Available Field Types

text email url number textarea code select multiselect toggle color image repeater

Field Definition Keys

KeyRequiredDescription
keyRequiredOption key used with get_option() / update_option().
labelRequiredHuman-readable field label.
typeRequiredOne of the field types listed above.
defaultOptionalDefault value when no setting exists.
descriptionOptionalHelp text shown below the field.
requiredOptionalBoolean. Adds server-side required validation.
optionsConditionalRequired for select and multiselect. Array of 'value' => 'Label'.
$this->register_settings([
    [
        'key'         => 'api_key',
        'label'       => 'API Key',
        'type'        => 'text',
        'required'    => true,
        'description' => 'Your Acme API key from dashboard.acme.com',
    ],
    [
        'key'     => 'mode',
        'label'   => 'Operating Mode',
        'type'    => 'select',
        'default' => 'sandbox',
        'options' => [
            'sandbox' => 'Sandbox (testing)',
            'live'    => 'Live (production)',
        ],
    ],
    [
        'key'     => 'enabled',
        'label'   => 'Enable Plugin',
        'type'    => 'toggle',
        'default' => true,
    ],
]);

// Retrieve anywhere in your plugin:
$key = $this->get_option('api_key');
$mode = $this->get_option('mode', 'sandbox');
Note

ℹ️ Settings are automatically scoped to the current tenant_id when the plugin type is tenant or both. Landlord-set values serve as global defaults that tenants can override.

Still stuck?
Our support team is ready to help you get set up.
Get support