Admin Panel API for plugins
Page summary:
The Admin Panel API exposes
register,bootstrap, andregisterTradshooks to inject React components and translations into Strapi’s UI. Menu, settings, injection zone, reducer, and hook APIs let plugins add navigation, configuration panels, or custom actions.
A Strapi plugin can interact with both the back end and the front end of a Strapi application. The Admin Panel API is about the front end part, i.e. it allows a plugin to customize Strapi's admin panel.
The admin panel is a React application that can embed other React applications. These other React applications are the admin parts of each Strapi plugin.
You have created a Strapi plugin.
The Admin Panel API includes:
- an entry file which exports the required interface,
- lifecycle functions and the
registerTrad()async function, - and several specific APIs for your plugin to interact with the admin panel.
The whole code for the admin panel part of your plugin could live in the /strapi-admin.js|ts or /admin/src/index.js|ts file. However, it's recommended to split the code into different folders, just like the structure created by the strapi generate plugin CLI generator command.
Entry file
The entry file for the Admin Panel API is [plugin-name]/admin/src/index.js. This file exports the required interface, with the following functions available:
| Function type | Available functions |
|---|---|
| Lifecycle functions | |
| Async function | registerTrads |
Lifecycle functions
register()
Type: Function
This function is called to load the plugin, even before the app is actually bootstrapped. It takes the running Strapi application as an argument (app).
Within the register function, a plugin can:
- register itself so it's available to the admin panel
- add a new link to the main navigation (see Menu API)
- create a new settings section
- define injection zones
- add reducers
registerPlugin()
Type: Function
Registers the plugin to make it available in the admin panel.
This function returns an object with the following parameters:
| Parameter | Type | Description |
|---|---|---|
id | String | Plugin id |
name | String | Plugin name |
injectionZones | Object | Declaration of available injection zones |
Some parameters can be imported from the package.json file.
Example:
// Auto-generated component
import PluginIcon from './components/PluginIcon';
import pluginId from './pluginId'
export default {
register(app) {
app.addMenuLink({
to: `/plugins/${pluginId}`,
icon: PluginIcon,
intlLabel: {
id: `${pluginId}.plugin.name`,
defaultMessage: 'My plugin',
},
Component: async () => {
const component = await import(/* webpackChunkName: "my-plugin" */ './pages/App');
return component;
},
permissions: [], // array of permissions (object), allow a user to access a plugin depending on its permissions
});
app.registerPlugin({
id: pluginId,
name,
});
},
};
bootstrap()
Type: Function
Exposes the bootstrap function, executed after all the plugins are registered.
Within the bootstrap function, a plugin can, for instance:
- extend another plugin, using
getPlugin('plugin-name'), - register hooks (see Hooks API),
- add links to a settings section,
- add actions and options to the Content Manager's List view and Edit view (see details on the Content Manager APIs page).
Example:
module.exports = () => {
return {
// ...
bootstrap(app) {
// execute some bootstrap code
app.getPlugin('content-manager').injectComponent('editView', 'right-links', { name: 'my-compo', Component: () => 'my-compo' })
},
};
};
Async function
While register() and bootstrap() are lifecycle functions, registerTrads() is an async function.
registerTrads()
Type: Function
To reduce the build size, the admin panel is only shipped with 2 locales by default (en and fr). The registerTrads() function is used to register a plugin's translations files and to create separate chunks for the application translations. It does not need to be modified.
Example: Register a plugin's translation files
export default {
async registerTrads({ locales }) {
const importedTrads = await Promise.all(
locales.map(locale => {
return import(
/* webpackChunkName: "[pluginId]-[request]" */ `./translations/${locale}.json`
)
.then(({ default: data }) => {
return {
data: prefixPluginTranslations(data, pluginId),
locale,
};
})
.catch(() => {
return {
data: {},
locale,
};
});
})
);
return Promise.resolve(importedTrads);
},
};
Available actions
The Admin Panel API allows a plugin to take advantage of several small APIs to perform actions. Use this table as a reference:
| Action | API to use | Function to use | Related lifecycle function |
|---|---|---|---|
| Add a new link to the main navigation | Menu API | addMenuLink() | register() |
| Create a new settings section | Settings API | createSettingSection() | register() |
| Declare an injection zone | Injection Zones API | registerPlugin() | register() |
| Add a reducer | Reducers API | addReducers() | register() |
| Create a hook | Hooks API | createHook() | register() |
| Add a single link to a settings section | Settings API | addSettingsLink() | bootstrap() |
| Add multiple links to a settings section | Settings API | addSettingsLinks() | bootstrap() |
| Inject a Component in an injection zone | Injection Zones API | injectComponent() | bootstrap() |
| Add options and actions to the Content Manager's Edit view and List view | Content Manager APIs |
| bootstrap() |
| Register a hook | Hooks API | registerHook() | bootstrap() |
The WYSIWYG editor can be replaced by taking advantage of custom fields, for instance using the CKEditor custom field plugin.
The admin panel supports dotenv variables.
All variables defined in a .env file and prefixed by STRAPI_ADMIN_ are available while customizing the admin panel through process.env.
Menu API
The Menu API allows a plugin to add a new link to the main navigation through the addMenuLink() function with the following parameters:
| Parameter | Type | Description |
|---|---|---|
to | String | Path the link should point to |
icon | React Component | Icon to display in the main navigation |
intlLabel | Object | Label for the link, following the React Int'l convention, with:
|
Component | Async function | Returns a dynamic import of the plugin entry point |
permissions | Array of Objects | Permissions declared in the permissions.js file of the plugin |
position | Integer | Position in the menu |
licenseOnly | Boolean | If set to true, adds a lightning ⚡️ icon next to the icon or menu entry to indicate that the feature or plugin requires a paid license.(Defaults to false) |
intlLabel.id are ids used in translation files ([plugin-name]/admin/src/translations/[language].json)
Example:
- JavaScript
- TypeScript
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: () => 'My plugin',
permissions: [], // permissions to apply to the link
position: 3, // position in the menu
licenseOnly: true, // mark the feature as a paid one not available in your license
});
app.registerPlugin({ ... });
},
bootstrap() {},
};
import PluginIcon from './components/PluginIcon';
import type { StrapiApp } from '@strapi/admin/strapi-admin';
export default {
register(app: StrapiApp) {
app.addMenuLink({
to: '/plugins/my-plugin',
icon: PluginIcon,
intlLabel: {
id: 'my-plugin.plugin.name',
defaultMessage: 'My plugin',
},
Component: () => 'My plugin',
permissions: [], // permissions to apply to the link
position: 3, // position in the menu
licenseOnly: true, // mark the feature as a paid one not available in your license
});
app.registerPlugin({ ... });
},
bootstrap() {},
};
Settings API
The Settings API allows:
- creating a new setting section
- adding a single link or multiple links at once to existing settings sections
Adding a new section happens in the register lifecycle while adding links happens during the bootstrap lifecycle.
All functions accept links as objects with the following parameters:
| Parameter | Type | Description |
|---|---|---|
id | String | React id |
to | String | Path the link should point to |
intlLabel | Object | Label for the link, following the React Int'l convention, with:
|
Component | Async function | Returns a dynamic import of the plugin entry point |
permissions | Array of Objects | Permissions declared in the permissions.js file of the plugin |
licenseOnly | Boolean | If set to true, adds a lightning ⚡️ icon next to the icon or menu entry to indicate that the feature or plugin requires a paid license.(Defaults to false) |