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.
- Any plugin update could break this plugin's extensions.
- New versions of Strapi are released with migration guides when required, but these guides never cover plugin extensions. Consider forking a plugin if extensive customizations are required.
- Currently, the admin panel part of a plugin can only be extended using patch-package, but please consider that doing so might break your plugin in future versions of Strapi.
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
model.json
/another-content-type-to-extend
model.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
content-types
key exported 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/extensions
folder 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-types
subfolder. - Inside the
content-types
subfolder, create another subfolder with the same singularName as the content-type to overwrite. - Inside this
content-types/name-of-content-type
subfolder, define the new schema for the content-type in aschema.json
file (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/extensions
are loaded. - The
register()
andbootstrap()
functions in./src/index.js|ts
are 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
).
If your Strapi project is TypeScript-based, please ensure that the index
file has a TypeScript extension (i.e., src/index.ts
) otherwise it will not be compiled.
Within the extensions folder
To extend a plugin's server interface using the ./src/extensions
folder:
- (optional) Create the
./src/extensions
folder 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|ts
file to extend a plugin's back end using the Server API. - Within this file, define and export a function. The function receives the
plugin
interface 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;
};
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 }) {},
};