Plugins extension#
Existing plugins can be overriden by placing code in `/src/extensions` or using global `register/bootstrap` hooks. Instructions in this documentation cover reshaping plugin content-type schemas or server logic — altough upstream updates may break extensions.Strapi comes with plugins that can be installed from the Marketplace or as npm packages. You can also create your own plugins (see plugins development) or extend the existing ones.
Plugin extensions code is located in the ./src/extensions folder (see project structure). Some plugins automatically create files there, ready to be modified.
Example of extensions folder structure
/extensions
/some-plugin-to-extend
strapi-server.js|ts
/content-types
/some-content-type-to-extend
schema.json
/another-content-type-to-extend
schema.json
/another-plugin-to-extend
strapi-server.js|ts
Plugins can be extended in 2 ways:
- extending the plugin's content-types
- extending the plugin's interface (e.g. to add controllers, services, policies, middlewares and more)
Extending a plugin's content-types#
A plugin's Content-Types can be extended in 2 ways: using the programmatic interface within strapi-server.js|ts and by overriding the content-types schemas.
The final schema of the content-types depends on the following loading order:
- the content-types of the original plugin,
- the content-types overridden by the declarations in the schema defined in
./src/extensions/plugin-name/content-types/content-type-name/schema.json - the content-types declarations in the
contentTypesexport fromstrapi-server.js|ts - the content-types declarations in the
register()function of the Strapi application
To overwrite a plugin's content-types:
- (optional) Create the
./src/extensionsfolder at the root of the app, if the folder does not already exist. - Create a subfolder with the same name as the plugin to be extended.
- Create a
content-typessubfolder. - Inside the
content-typessubfolder, create another subfolder with the same singularName as the content-type to overwrite. - Inside this
content-types/name-of-content-typesubfolder, define the new schema for the content-type in aschema.jsonfile (see schema documentation). - (optional) Repeat steps 4 and 5 for each content-type to overwrite.
Extending a plugin's interface#
When a Strapi application is initializing, plugins, extensions and global lifecycle functions events happen in the following order:
- Plugins are loaded and their interfaces are exposed.
- Files in
./src/extensionsare loaded. - The
register()andbootstrap()functions in./src/index.js|tsare called.
A plugin's interface can be extended at step 2 (i.e. within ./src/extensions) or step 3 (i.e. inside ./src/index.js|ts).
Within the extensions folder#
To extend a plugin's server interface using the ./src/extensions folder:
- (optional) Create the
./src/extensionsfolder at the root of the app, if the folder does not already exist. - Create a subfolder with the same name as the plugin to be extended.
- Create a
strapi-server.js|tsfile to extend a plugin's back end using the Server API. - Within this file, define and export a function. The function receives the
plugininterface as an argument so it can be extended.
Example of backend extension
module.exports = (plugin) => {
plugin.controllers.controllerA.find = (ctx) => {};
plugin.policies[newPolicy] = (ctx) => {};
plugin.routes['content-api'].routes.push({
method: 'GET',
path: '/route-path',
handler: 'controller.action',
});
return plugin;
};
generateFileName() belongs to the Upload plugin's image-manipulation service and expects a single name: string argument.
This customization relies on an internal Upload plugin service (image-manipulation). Internal extension points are not part of Strapi's stable public API and can change between versions.
Within the register and bootstrap functions#
To extend a plugin's interface within ./src/index.js|ts, use the bootstrap() and register() functions of the whole project, and access the interface programmatically with getters.
Example of extending a plugin's content-type within ./src/index.js|ts
module.exports = {
register({ strapi }) {
const contentTypeName = strapi.contentType('plugin::my-plugin.content-type-name')
contentTypeName.attributes = {
// Spread previous defined attributes
...contentTypeName.attributes,
// Add new, or override attributes
'toto': {
type: 'string',
}
}
},
bootstrap({ strapi }) {},
};