# Plugins extension
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-admin.js
strapi-server.js
/content-types
/some-content-type-to-extend
model.json
/another-content-type-to-extend
model.json
/another-plugin-to-extend
strapi-admin.js
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)
A plugin's Content-Types can be extended in 2 ways: using the programmatic interface within strapi-server.js 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 overriden 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
content-typeskey exported fromstrapi-server.js - the content-types declarations in the
register()function of the Strapi application
️❗️ WARNING
New versions of Strapi are released with migration guides, but these guides might not cover unexpected breaking changes in your plugin extensions. Consider forking a plugin if extensive customizations are required.
# Extending a plugin's Content-Types
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.jsare 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).
# Within the extensions folder
To extend a plugin's 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.
- Depending on what needs to be extended:
- create a
strapi-server.jsfile to extend a plugin's back end using the Server API - or create a
strapi-admin.jsfile to extend the admin panel with the Admin Panel API.
- create a
- 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
// path: ./src/extensions/some-plugin-to-extend/strapi-server.js
module.exports = (plugin) => {
plugin.controllers.controllerA.find = (ctx) => {};
plugin.policies[newPolicy] = (ctx) => {};
plugin.routes.push({
method: 'GET',
path: '/route-path',
handler: 'controller.action',
});
return plugin;
};
# Within the register and bootstrap functions
To extend a plugin's interface within ./src/index.js, 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
// path: ./src/index.js
module.exports = {
register({ strapi }) {
strapi.contentType('plugin::my-plugin.content-type-name').attributes = {
'toto': {
type: 'string',
}
}
},
bootstrap({ strapi }) {},
};