Skip to main content

Plugins extension

🏗 Work in progress

The content of this page might not be fully up-to-date with Strapi 5 yet.

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.

Warning
  • Any plugin update could break this plugin's extensions.
  • New versions of Strapi will be 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 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:

  1. the content-types of the original plugin,
  2. the content-types overridden by the declarations in the schema defined in ./src/extensions/plugin-name/content-types/content-type-name/schema.json
  3. the content-types declarations in the content-types key exported from strapi-server.js|ts
  4. the content-types declarations in the register() function of the Strapi application

To overwrite a plugin's content-types:

  1. (optional) Create the ./src/extensions folder at the root of the app, if the folder does not already exist.
  2. Create a subfolder with the same name as the plugin to be extended.
  3. Create a content-types subfolder.
  4. Inside the content-types subfolder, create another subfolder with the same singularName as the content-type to overwrite.
  5. Inside this content-types/name-of-content-type subfolder, define the new schema for the content-type in a schema.json file (see schema documentation).
  6. (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:

  1. Plugins are loaded and their interfaces are exposed.
  2. Files in ./src/extensions are loaded.
  3. The register() and bootstrap() 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).

Note

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:

  1. (optional) Create the ./src/extensions folder at the root of the app, if the folder does not already exist.
  2. Create a subfolder with the same name as the plugin to be extended.
  3. Create a strapi-server.js|ts file to extend a plugin's back end using the Server API.
  4. 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
./src/extensions/some-plugin-to-extend/strapi-server.js|ts

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
./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 }) {},
};