Skip to main content

Admin Panel API: Navigation & settings

Page summary:

Use addMenuLink in register to add sidebar links, createSettingSection in register to create settings groups, and addSettingsLink/addSettingsLinks in bootstrap to extend existing settings sections.

Plugins can customize the admin panel's navigation sidebar and settings pages to provide access to their features. All functions described on this page are called within the register or bootstrap lifecycle functions of your plugin's entry file.

Prerequisites

Before diving deeper into the concepts on this page, please ensure you have:

The navigation sidebar is the main menu on the left side of the admin panel. Plugins can add links to this sidebar using the addMenuLink() method in the register lifecycle function.

Adding a link to the navigation sidebar is done with the addMenuLink() function, which should be registered through the register() lifecycle function of your plugin.

A menu link accepts the following parameters:

ParameterTypeRequiredDescription
tostringPath the link should point to (relative to the admin panel root) (see additional information)
iconReact.ComponentReact component for the icon to display in the navigation
intlLabelobjectLabel for the link, following the React Int'l convention, with:
  • id: id used to insert the localized label
  • defaultMessage: default label for the link
Componentasync functionAsync function that returns a dynamic import of the plugin's main page component
permissionsArray<object>Array of permission objects that control access to the link
positionnumberNumeric position in the menu (lower numbers appear first)
licenseOnlybooleanIf true, displays a ⚡ icon to indicate the feature requires a paid license (default: false)
Note

The intlLabel.id values should correspond to keys in your translation files located at admin/src/translations/[locale].json. See Admin localization for details.

Caution

The permissions parameter only controls whether the link is visible in the navigation. It does not protect the page itself. A user who knows the URL can still access the page directly. To fully secure a plugin route, you must also check permissions inside your page component and register your RBAC actions on the server side with actionProvider.registerMany. See the Admin permissions for plugins guide for a complete walkthrough.

admin/src/index.js
import PluginIcon from './components/PluginIcon';

export default {
register(app) {
app.addMenuLink({
to: `/plugins/my-plugin`,
icon: PluginIcon,
intlLabel: {
id: 'my-plugin.plugin.name',
defaultMessage: 'My Plugin',
},
Component: async () => {
const { App } = await import('./pages/App');
return App;
},
permissions: [], // Array of permission objects
position: 3, // Position in the menu (lower numbers appear first)
licenseOnly: false, // Set to true to show ⚡ icon for paid features
});

app.registerPlugin({
id: 'my-plugin',
name: 'My Plugin',
});
},
};

Settings

The Settings API allows plugins to create new settings sections or add links to existing sections. Settings sections are organized groups of configuration pages accessible from the Settings menu item in the navigation sidebar.

Creating a new settings section

Use createSettingSection() in the register lifecycle function:

admin/src/index.js
export default {
register(app) {
app.createSettingSection(
{
id: 'my-plugin',
intlLabel: {
id: 'my-plugin.settings.section-label',
defaultMessage: 'My Plugin Settings',
},
},
[
{
intlLabel: {
id: 'my-plugin.settings.general',
defaultMessage: 'General',
},
id: 'general',
to: 'my-plugin/general',
Component: async () => {
const { GeneralSettings } =
await import('./pages/Settings/General');
return GeneralSettings;
},
},
{
intlLabel: {
id: 'my-plugin.settings.advanced',
defaultMessage: 'Advanced',
},
id: 'advanced',
to: 'my-plugin/advanced',
Component: async () => {
const { AdvancedSettings } =
await import('./pages/Settings/Advanced');
return AdvancedSettings;
},
},
],
);

app.registerPlugin({
id: 'my-plugin',
name: 'My Plugin',
});
},
};

The createSettingSection() function accepts the following parameters:

  • the first argument is the section configuration:

    ParameterTypeRequiredDescription
    idstringUnique identifier for the settings section
    intlLabelobjectLocalized label for the section, following the React Int'l convention, with:
    • id: id used to insert the localized label
    • defaultMessage: default label for the section
  • the second argument is an array of link objects; each link object contains the following:

    ParameterTypeRequiredDescription
    idstringUnique identifier for the settings link
    tostringPath relative to the settings route (do not include settings/ prefix) (see additional information)
    intlLabelobjectLocalized label object with id and defaultMessage
    Componentasync functionAsync function that returns a dynamic import of the settings page component
    permissionsArray<object>Array of permission objects that control access to the link
    licenseOnlybooleanIf true, displays a ⚡ icon (default: false)

To add a single link to an existing settings section, use addSettingsLink() in the bootstrap() lifecycle function. To add multiple links at once, use addSettingsLinks().

admin/src/index.js
export default {
register(app) {
app.registerPlugin({
id: 'my-plugin',
name: 'My Plugin',
});
},
bootstrap(app) {
// Add a single link to the global settings section
app.addSettingsLink('global', {
intlLabel: {
id: 'my-plugin.settings.documentation',
defaultMessage: 'Documentation',
},
id: 'documentation',
to: 'my-plugin/documentation',
Component: async () => {
const { DocumentationPage } =
await import('./pages/Settings/Documentation');
return DocumentationPage;
},
permissions: [],
licenseOnly: false,
});

// Add multiple links at once to the global settings section
app.addSettingsLinks('global', [
{
intlLabel: {
id: 'my-plugin.settings.general',
defaultMessage: 'General',
},
id: 'general',
to: 'my-plugin/general',
Component: async () => {
const { GeneralSettings } =
await import('./pages/Settings/General');
return GeneralSettings;
},
},
{
intlLabel: {
id: 'my-plugin.settings.advanced',
defaultMessage: 'Advanced',
},
id: 'advanced',
to: 'my-plugin/advanced',
Component: async () => {
const { AdvancedSettings } =
await import('./pages/Settings/Advanced');
return AdvancedSettings;
},
},
]);
},
};

addSettingsLink and addSettingsLinks both take a sectionId string as the first argument (e.g., 'global' or 'permissions'). The second argument is a single link object for addSettingsLink or an array of link objects for addSettingsLinks, using the same properties as the links array in createSettingSection() (see table above).

Available settings sections

Strapi provides built-in settings sections that plugins can extend:

  • global: General application settings
  • permissions: Administration panel settings
Note

Creating a new settings section must be done in the register lifecycle function. Adding links to existing settings sections must be done in the bootstrap lifecycle function.

Path conventions for to

The to parameter behaves differently depending on the context:

Contextto valueFinal URL
addMenuLink/plugins/my-pluginhttp://localhost:1337/admin/plugins/my-plugin
createSettingSection linkmy-plugin/generalhttp://localhost:1337/admin/settings/my-plugin/general
addSettingsLinkmy-plugin/documentationhttp://localhost:1337/admin/settings/my-plugin/documentation

For menu links, the path is relative to the admin panel root (/admin). For settings links, the path is relative to the settings route (/admin/settings). Do not include the settings/ prefix in settings link paths.

Securing plugin routes

The permissions parameter on links only controls visibility in the navigation. To fully protect your plugin pages and register RBAC actions, see the Admin permissions for plugins guide.