diff --git a/docusaurus/docs/cms/plugins-development/create-a-plugin.md b/docusaurus/docs/cms/plugins-development/create-a-plugin.md
index 2a5f9d3c93..f8324a8079 100644
--- a/docusaurus/docs/cms/plugins-development/create-a-plugin.md
+++ b/docusaurus/docs/cms/plugins-development/create-a-plugin.md
@@ -11,29 +11,25 @@ tags:
# Plugin creation
-There are many ways to create a Strapi 5 plugin, but the fastest and recommended way is to use the Plugin SDK.
+This guide walks you through the complete process of creating, developing, and publishing Strapi 5 plugins that can be used locally or distributed via NPM and the Marketplace. The Plugin SDK is the recommended way to build plugins, providing a comprehensive toolkit from initial setup to publishing.
-The Plugin SDK is a set of commands orientated around developing plugins to use them as local plugins or to publish them on NPM and/or submit them to the Marketplace.
+The complete list of commands and their parameters are available in the [Plugin SDK reference](/cms/plugins-development/plugin-sdk). This page will guide you through using the main ones.
-With the Plugin SDK, you do not need to set up a Strapi project before creating a plugin.
+Before proceeding with plugin development, it's important to understand the difference between local and external plugins:
-The present guide covers creating a plugin from scratch, linking it to an existing Strapi project, and publishing the plugin. If you already have an existing plugin, you can instead retrofit the plugin setup to utilise the Plugin SDK commands (please refer to the [Plugin SDK reference](/cms/plugins-development/plugin-sdk) for a full list of available commands).
+- **Local plugins**: Plugins that are developed within your Strapi project (typically in a `plugins` folder).
+- **External plugins**: Plugins that are developed outside your Strapi project (in a separate directory).
-:::note
-This guide assumes you want to develop a plugin external to your Strapi project. However, the steps largely remain the same if you want to develop a plugin within your existing project. If you are not [using a monorepo](#monorepo) the steps are exactly the same.
-:::
-
-:::prerequisites
- must be installed globally (with `npm install -g yalc` or `yarn global add yalc`).
-:::
+The Plugin SDK can create both types of plugins. If you run the Plugin SDK command from within an existing Strapi project, it will create a local plugin. If you run it from outside a Strapi project, it will create an external plugin. The development process differs slightly between the two approaches, as outlined in the sections below.
-## Getting started with the Plugin SDK
+In addition to the plugin location, your Strapi project and plugin can be organized in different repository setups, which affects the development workflow:
-The Plugin SDK helps you creating a plugin, linking it to an existing Strapi project, and building it for publishing.
+- **Separate repositories**: Your Strapi project and plugin are in different repositories. This is common for external plugins that you plan to publish or share across multiple projects.
+- **Monorepo setup**: Your Strapi project and plugin are in the same repository, often using workspace management tools like Yarn workspaces or npm workspaces. This is useful when you want to maintain everything in one place.
-The full list of commands and their parameters are available in the [Plugin SDK reference](/cms/plugins-development/plugin-sdk). The present page will guide on using the main ones.
+The development workflow and commands you use will vary based on both the plugin type (local vs external) and the repository setup (separate vs monorepo), as detailed in the sections below.
-### Creating the plugin
+## Creating the plugin
To create your plugin, ensure you are in the parent directory of where you want it to be created and run the following command:
@@ -59,23 +55,45 @@ npx @strapi/sdk-plugin init my-strapi-plugin
The path `my-strapi-plugin` can be replaced with whatever you want to call your plugin, including the path to where it should be created (e.g., `code/strapi-plugins/my-new-strapi-plugin`).
-You will be ran through a series of prompts to help you setup your plugin. If you selected yes to all options the final structure will be similar to the default [plugin structure](/cms/plugins-development/plugin-structure).
+You will be guided through a series of prompts to help you set up your plugin. If you select "yes" to all options, the final structure will be similar to the default [plugin structure](/cms/plugins-development/plugin-structure).
+
+## Developing local plugins
+
+If you run the Plugin SDK command from within an existing Strapi project, the plugin will be created in a `plugins` folder within that project. If a `plugins` folder already exists, the new plugin code will be placed there. This allows you to develop plugins locally within your project structure.
+
+When developing your plugin locally, you also need to add the following configuration to your plugins configuration file:
+
+```js title="/config/plugins.js|ts"
+myplugin: {
+ enabled: true,
+ resolve: `./src/plugins/local-plugin`,
+},
+```
+
+:::note
+This setup can sometimes lead to errors such as:
-### Linking the plugin to your project
+```js
+Error: 'X must be used within StrapiApp';
+```
-In order to test your plugin during its development, the recommended approach is to link it to a Strapi project.
+This error often occurs when your plugin attempts to import core Strapi functionality, for example using:
-Linking your plugin to a project is done with the `watch:link` command. The command will output explanations on how to link your plugin to a Strapi project.
+```js
+import { unstable_useContentManagerContext as useContentManagerContext } from '@strapi/strapi/admin';
+```
+
+To resolve this issue, remove `@strapi/strapi` as a dev dependency from your plugin. This ensures that your plugin uses the same instance of Strapi's core modules as the main application, preventing conflicts and the associated errors.
+:::
-In a new terminal window, run the following commands:
+Use the `watch` command in your plugin folder to start development mode:
```bash
-cd /path/to/strapi/project
-yarn dlx yalc add --link my-strapi-plugin && yarn install
+yarn watch
```
@@ -83,34 +101,33 @@ yarn dlx yalc add --link my-strapi-plugin && yarn install
```bash
-cd /path/to/strapi/project
-npx yalc add --link my-strapi-plugin && npm install
+npm run watch
```
-:::note
-In the above examples we use the name of the plugin (`my-strapi-plugin`) when linking it to the project. This is the name of the package, not the name of the folder.
-:::
+Then run `yarn develop` or `npm run develop` in your Strapi project to start the application with your local plugin.
-Because this plugin is installed via `node_modules` you won't need to explicity add it to your `plugins` [configuration file](/cms/configurations/plugins), so running the [`develop command`](/cms/cli#strapi-develop) to start your Strapi project will automatically pick up your plugin.
+## Developing external plugins
-Now that your plugin is linked to a project, run `yarn develop` or `npm run develop` to start the Strapi application.
+:::prerequisites
+ must be installed globally (with `npm install -g yalc` or `yarn global add yalc`).
-You are now ready to develop your plugin how you see fit! If you are making server changes, you will need to restart your server for them to take effect.
+**Why yalc?** `yalc` is a local package manager that enables efficient plugin development by allowing you to test your plugin in a real Strapi project without publishing it to npm first. It provides reliable linking between your plugin and Strapi project for immediate testing during development.
+:::
-### Building the plugin for publishing
+For external plugins (plugins that don't sit within your Strapi project), you need to link them to a Strapi project for testing during development. This is done using the `watch:link` command in your plugin folder, which will output explanations on how to link your plugin to a Strapi project.
-When you are ready to publish your plugin, you will need to build it. To do this, run the following command:
+First, in your plugin folder, run the `watch:link` command:
```bash
-yarn build && yarn verify
+yarn watch:link
```
@@ -118,108 +135,94 @@ yarn build && yarn verify
```bash
-npm run build && npm run verify
+npm run watch:link
```
-The above commands will not only build the plugin, but also verify that the output is valid and ready to be published. You can then publish your plugin to NPM as you would any other package.
+Then, in a new terminal window, run the following commands in your Strapi project:
-## Working with the Plugin SDK in a monorepo environment {#monorepo}
+
-If you are working with a monorepo environment to develop your plugin, you don't need to use the `watch:link` command because the monorepo workspace setup will handle the symlink. You can use the `watch` command instead.
+
-However, if you are writing admin code, you might add an `alias` that targets the source code of your plugin to make it easier to work with within the context of the admin panel:
+```bash
+cd /path/to/strapi/project
+yarn dlx yalc add --link my-strapi-plugin && yarn install
+```
-```ts
-import path from 'node:path';
+
-export default (config, webpack) => {
- config.resolve.alias = {
- ...config.resolve.alias,
- 'my-strapi-plugin': path.resolve(
- __dirname,
- // We've assumed the plugin is local.
- '../plugins/my-strapi-plugin/admin/src'
- ),
- };
+
- return config;
-};
+```bash
+cd /path/to/strapi/project
+npx yalc add --link my-strapi-plugin && npm install
```
-:::caution
-Because the server looks at the `server/src/index.ts|js` file to import your plugin code, you must use the `watch` command otherwise the code will not be transpiled and the server will not be able to find your plugin.
+
+
+
+
+:::note
+In the above examples, we use the name of the plugin (`my-strapi-plugin`) when linking it to the project. This is the name of the package, not the name of the folder.
:::
-### Configuration with a local plugin
+:::note
+If you're working in a monorepo environment, you don't need `yalc` because the monorepo workspace setup handles the symlinking automatically.
+:::
-Since the Plugin SDK is primarily designed for developing plugins, not locally, the configuration needs to be adjusted manually for local plugins.
+Because this plugin is installed via `node_modules`, you won't need to explicitly add it to your `plugins` configuration file as we would do for a local plugin. Running the `develop` command to start your Strapi project will automatically pick up your plugin.
-When developing your plugin locally (using `@strapi/sdk-plugin`), your plugins configuration file looks like in the following example:
+Now that your plugin is linked to a project, run `yarn develop` or `npm run develop` to start the Strapi application.
-```js title="/config/plugins.js|ts"
-myplugin: {
- enabled: true,
- resolve: `./src/plugins/local-plugin`,
-},
-```
+You are now ready to develop your plugin as needed! If you are making server changes, you will need to restart your server for them to take effect.
-However, this setup can sometimes lead to errors such as the following:
+## Building the plugin for publishing
-```js
-Error: 'X must be used within StrapiApp';
-```
+When you are ready to publish your plugin, you will need to build it. To do this, run the following command:
-This error often occurs when your plugin attempts to import core Strapi functionality, for example using:
+
-```js
-import { unstable_useContentManagerContext as useContentManagerContext } from '@strapi/strapi/admin';
+
+
+```bash
+yarn build && yarn verify
```
-To resolve the issue, remove `@strapi/strapi` as a dev dependency from your plugin. This ensures that your plugin uses the same instance of Strapi’s core modules as the main application, preventing conflicts and the associated errors.
+
-## Setting a local plugin in a monorepo environment without the Plugin SDK
+
-In a monorepo, you can configure your local plugin without using the Plugin SDK by adding 2 entry point files at the root of your plugin:
+```bash
+npm run build && npm run verify
+```
-- server entry point: `strapi-server.js|ts`
-- admin entry point: `strapi-admin.js|ts`
+
-### Server entry point
+
-The server entry point file initializes your plugin’s server-side functionalities. The expected structure for `strapi-server.js` (or its TypeScript variant) is:
+These commands will not only build the plugin but also verify that the output is valid and ready to be published. You can then publish your plugin to NPM as you would any other package.
-```js
-module.exports = () => {
- return {
- register,
- config,
- controllers,
- contentTypes,
- routes,
- };
-};
-```
+## Admin panel development
-Here, you export a function that returns your plugin's core components such as controllers, routes, and configuration. For more details, please refer to the [Server API reference](/cms/plugins-development/server-api).
+If you are writing admin code, you might add an `alias` that targets the source code of your plugin to make it easier to work with within the context of the admin panel:
-### Admin entry point
+```ts
+import path from 'node:path';
-The admin entry point file sets up your plugin within the Strapi admin panel. The expected structure for `strapi-admin.js` (or its TypeScript variant) is:
+export default (config, webpack) => {
+ config.resolve.alias = {
+ ...config.resolve.alias,
+ 'my-strapi-plugin': path.resolve(
+ __dirname,
+ // We've assumed the plugin is local.
+ '../plugins/my-strapi-plugin/admin/src'
+ ),
+ };
-```js
-export default {
- register(app) {},
- bootstrap() {},
- registerTrads({ locales }) {},
+ return config;
};
```
-
-This object includes methods to register your plugin with the admin application, perform bootstrapping actions, and handle translations. For more details, please refer to the [Admin Panel API reference](/cms/plugins-development/admin-panel-api).
-
-:::tip
-For a complete example of how to structure your local plugin in a monorepo environment, please check out our .
-:::
diff --git a/docusaurus/static/llms-full.txt b/docusaurus/static/llms-full.txt
index 909057bd38..673d4b4b21 100644
--- a/docusaurus/static/llms-full.txt
+++ b/docusaurus/static/llms-full.txt
@@ -6881,15 +6881,49 @@ The `./src/index.js` file (or `./src/index.ts` file in a [TypeScript-based](/cms
The functions can be synchronous, asynchronous, or return a promise.
-
+
-## Asynchronous function
+## Why do we need lifecycle functions?
-
+When Strapi starts up, it follows a well-defined sequence of steps to ensure that everything is properly initialized before handling requests. These steps are crucial because they allow different parts of the system—such as plugins, middleware, and database connections—to be set up in a logical order.
-## Function returning a promise
+Think of Strapi **like a car starting up**.
+When you start a car, you don't just turn the key and instantly drive off. **There's a process that happens in steps:**
-
+1. **The car's engine turns on (loading the core).** This is like Strapi preparing its core system—turning on the "engine" of the app.
+ Without this step, nothing else can run.
+2. **The car checks its internal systems (register step).**
+ The dashboard lights come on, the fuel pump activates, and the car checks if everything is working.
+ This is like Strapi setting up its middleware, plugins, and services before they actually start running.
+ You cannot drive yet because the car is still getting ready.
+3. **The car is now fully on, and you can drive (bootstrap step).**
+ Now you can press the gas pedal, move the car, turn on the air conditioning, and start using everything.
+ This is when Strapi is fully ready, and you can safely interact with the database, set up roles, and run scheduled jobs.
+
+Without these lifecycle hooks, developers would have no structured way to intervene in Strapi's initialization process. And so, with the lifecycle functions, Strapi provides a mechanism to:
+
+- allow modifications before the app fully starts (register)
+- execute custom logic after Strapi is completely ready (bootstrap).
+
+```mermaid
+flowchart TB
+ A([The Strapi application starts.]) --> B{"register()"}
+ B -- The Strapi application is setup. --> C
+ C{"bootstrap()"} -- The Strapi back-end server starts. --> D
+ D(Request)
+ D
+ click B "#register"
+ click C "#bootstrap"
+ click D "/dev-docs/backend-customization/requests-responses"
+```
+
+### Strapi lifecycle functions: register, bootstrap, and destroy
+
+| Phase | When It Happens | Purpose | Common use cases |
+| --------- | ---------------------------- | ---------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
+| register | Before Strapi fully starts | Set up services, modify configurations, and register middleware | Define custom services, register middleware, modify plugin configurations, set up event listeners |
+| bootstrap | After Strapi is fully loaded | Execute custom logic that requires Strapi to be fully running | Seed database with initial data, create default user roles, start cron jobs or background tasks, perform API calls to external services |
+| destroy | When Strapi is shutting down | Clean up resources, close connections, and handle shutdown logic | Close database connections, stop background tasks (cron jobs, message queues, etc.), gracefully shut down third-party services |
## Register
@@ -6914,7 +6948,7 @@ It can be used to:
- fill the database with some necessary data
- declare custom conditions for the [Role-Based Access Control (RBAC)](/cms/configurations/guides/rbac) feature
-The `bootstrapi()` function is run _before_ the back-end server starts but _after_ the Strapi application has setup, so you have access to anything from the `strapi` object.
+The `bootstrap()` function is run _before_ the back-end server starts but _after_ the Strapi application has setup, so you have access to anything from the `strapi` object.
:::tip
You can run `yarn strapi console` (or `npm run strapi console`) in the terminal and interact with the `strapi` object.
@@ -9130,490 +9164,78 @@ Follow the steps below and leverage retro-compatibility flags and guided migrati
# Admin Panel API
Source: https://docs.strapi.io/cms/plugins-development/admin-panel-api
-# Admin Panel API for plugins
+Strapi provides a flexible and extensible admin panel that can be customized through plugins. This documentation outlines how to enhance the Strapi admin panel by modifying the interface, injecting components, and integrating custom features.
A Strapi plugin can interact with both the [back end](/cms/plugins-development/server-api) 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](/cms/intro).
-The admin panel is a
-
-
-
-### Settings API
+The admin panel is a application that can embed other React applications. These other React applications are the admin parts of each Strapi plugin.
-The Settings API allows:
-
-* [creating a new setting section](#createsettingsection)
-* adding [a single link](#addsettingslink) or [multiple links at once](#addsettingslinks) to existing settings sections
-
-:::note
-Adding a new section happens in the [register](#register) lifecycle while adding links happens during the [bootstrap](#bootstrap) lifecycle.
+:::prerequisites
+You have [created a Strapi plugin](/cms/plugins-development/create-a-plugin).
:::
-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 convention, with:
- `id`: id used to insert the localized label
- `defaultMessage`: default label for the link
|
-| `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`) |
+The Admin Panel API includes:
-#### createSettingSection()
-
-**Type**: `Function`
-
-Create a new settings section.
-
-The function takes 2 arguments:
-
-| Argument | Type | Description |
-| --------------- | ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| first argument | Object | Section label:- `id` (String): section id
- `intlLabel` (Object): localized label for the section, following the convention, with:
- `id`: id used to insert the localized label
- `defaultMessage`: default label for the section
|
-| second argument | Array of Objects | Links included in the section |
+- an [entry file](#entry-file) which exports the required interface,
+- [lifecycle functions](#lifecycle-functions) and the `registerTrad()` [async function](#async-function),
+- and several [specific APIs](#available-actions) for your plugin to interact with the admin panel.
:::note
-`intlLabel.id` are ids used in translation files (`[plugin-name]/admin/src/translations/[language].json`)
+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](/cms/plugins-development/plugin-structure) created by the `strapi generate plugin` CLI generator command.
:::
-**Example:**
-
-```jsx title="my-plugin/admin/src/index.js"
-
-const myComponent = async () => {
- const component = await import(
- /* webpackChunkName: "users-providers-settings-page" */ './pages/Providers'
- );
-
- return component;
-};
-
- register(app) {
- app.createSettingSection(
- { id: String, intlLabel: { id: String, defaultMessage: String } }, // Section to create
- [
- // links
- {
- intlLabel: { id: String, defaultMessage: String },
- id: String,
- to: String,
- Component: myComponent,
- permissions: Object[],
- },
- ]
- );
- },
-};
-```
-
-#### addSettingsLink()
-
-**Type**: `Function`
-
-Add a unique link to an existing settings section.
-
-**Example:**
-
-```jsx title="my-plugin/admin/src/index.js"
+## Entry file
-const myComponent = async () => {
- const component = await import(
- /* webpackChunkName: "users-providers-settings-page" */ './pages/Providers'
- );
+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:
- return component;
-};
+| Function type | Available functions |
+| ------------------- | ------------------------------------------------------------------------ |
+| Lifecycle functions | - [register](#register)
- [bootstrap](#bootstrap)
|
+| Async function | [registerTrads](#registertrads) |
- bootstrap(app) {
- // Adding a single link
- app.addSettingsLink(
- 'global', // id of the section to add the link to
- {
- intlLabel: { id: String, defaultMessage: String },
- id: String,
- to: String,
- Component: myComponent,
- permissions: Object[],
- licenseOnly: true, // mark the feature as a paid one not available in your license
- }
- )
- }
-}
-```
-
-#### addSettingsLinks()
+## Lifecycle functions
-**Type**: `Function`
+
-Add multiple links to an existing settings section.
+### register()
-**Example:**
+**Type:** `Function`
-```jsx title="my-plugin/admin/src/index.js"
+This function is called to load the plugin, even before the app is actually [bootstrapped](#bootstrap). It takes the running Strapi application as an argument (`app`).
-const myComponent = async () => {
- const component = await import(
- /* webpackChunkName: "users-providers-settings-page" */ './pages/Providers'
- );
+Within the register function, a plugin can:
- return component;
-};
+- [register itself](#registerplugin) so it's available to the admin panel
+- add a new link to the main navigation (see [Menu API](#menu-api))
+- [create a new settings section](#createsettingsection)
+- define [injection zones](#injection-zones-api)
+- [add reducers](#reducers-api)
- bootstrap(app) {
- // Adding several links at once
- app.addSettingsLinks(
- 'global', // id of the section to add the link in
- [{
- intlLabel: { id: String, defaultMessage: String },
- id: String,
- to: String,
- Component: myComponent,
- permissions: Object[],
- licenseOnly: true, // mark the feature as a paid one not available in your license
- }]
- )
- }
-}
-```
+#### registerPlugin()
-### Injection Zones API
+**Type:** `Function`
-Injection zones refer to areas of a view's layout where a plugin allows another to inject a custom React component (e.g. a UI element like a button).
+Registers the plugin to make it available in the admin panel.
-Plugins can use:
+This function returns an object with the following parameters:
-* Strapi's [predefined injection zones](#using-predefined-injection-zones) for the Content Manager,
-* or custom injection zones, created by a plugin
+| Parameter | Type | Description |
+| ---------------- | ------ | ---------------------------------------------------------------- |
+| `id` | String | Plugin id |
+| `name` | String | Plugin name |
+| `injectionZones` | Object | Declaration of available [injection zones](#injection-zones-api) |
:::note
-Injection zones are defined in the [register()](#register) lifecycle but components are injected in the [bootstrap()](#bootstrap) lifecycle.
+Some parameters can be imported from the `package.json` file.
:::
-#### Using predefined injection zones
-
-Strapi admin panel comes with predefined injection zones so components can be added to the UI of the [Content Manager](/cms/intro):
-
-
-
-| View | Injection zone name & Location |
-| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| List view | `actions`: sits between Filters and the cogs icon
-| Edit view | `right-links`: sits between "Configure the view" and "Edit" buttons |
-
-#### Creating a custom injection zone
-
-To create a custom injection zone, declare it as a `` React component with an `area` prop that takes a string with the following naming convention: `plugin-name.viewName.injectionZoneName`.
-
-#### Injecting components
-
-A plugin has 2 different ways of injecting a component:
-
-* to inject a component from a plugin into another plugin's injection zones, use the `injectComponent()` function
-* to specifically inject a component into one of the Content Manager's [predefined injection zones](#using-predefined-injection-zones), use the `getPlugin('content-manager').injectComponent()` function instead
-
-Both the `injectComponent()` and `getPlugin('content-manager').injectComponent()` methods accept the following arguments:
-
-| Argument | Type | Description |
-| --------------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| first argument | String | The view where the component is injected
-| second argument | String | The zone where the component is injected
-| third argument | Object | An object with the following keys:- `name` (string): the name of the component
- `Component` (function or class): the React component to be injected
|
-
-
-Example: Inject a component in the informations box of the Edit View of the Content Manager:
-
-```jsx title="my-plugin/admin/src/index.js"
-
- bootstrap(app) {
- app.getPlugin('content-manager').injectComponent('editView', 'informations', {
- name: 'my-plugin-my-compo',
- Component: () => 'my-compo',
- });
- }
-}
-```
-
-
-
-
-Example: Creating a new injection zone and injecting it from a plugin to another one:
-
-```jsx title="my-plugin/admin/src/injectionZones.js"
-// Use the injection zone in a view
-
-const HomePage = () => {
- return (
-
- This is the homepage
-
-
- );
-};
-```
-
-```jsx title="my-plugin/admin/src/index.js"
-// Declare this injection zone in the register lifecycle of the plugin
-
- register() {
- app.registerPlugin({
- // ...
- injectionZones: {
- homePage: {
- right: []
- }
- }
- });
- },
-}
-```
-
-```jsx title="my-other-plugin/admin/src/index.js"
-// Inject the component from a plugin in another plugin
-
- register() {
- // ...
- },
- bootstrap(app) {
- app.getPlugin('my-plugin').injectComponent('homePage', 'right', {
- name: 'my-other-plugin-component',
- Component: () => 'This component is injected',
- });
- }
-};
-```
-
-
-
-#### Accessing data with the `useCMEditViewDataManager` React hook
-
-Once an injection zone is defined, the component to be injected in the Content Manager can have access to all the data of the Edit View through the `useCMEditViewDataManager` React hook.
-
-
-Example of a basic component using the 'useCMEditViewDataManager' hook
-
-```js
-
-const MyCompo = () => {
- const {
- createActionAllowedFields: [], // Array of fields that the user is allowed to edit
- formErrors: {}, // Object errors
- readActionAllowedFields: [], // Array of field that the user is allowed to edit
- slug: 'api::address.address', // Slug of the content-type
- updateActionAllowedFields: [],
- allLayoutData: {
- components: {}, // components layout
- contentType: {}, // content-type layout
- },
- initialData: {},
- isCreatingEntry: true,
- isSingleType: true,
- status: 'resolved',
- layout: {}, // Current content-type layout
- hasDraftAndPublish: true,
- modifiedData: {},
- onPublish: () => {},
- onUnpublish: () => {},
- addComponentToDynamicZone: () => {},
- addNonRepeatableComponentToField: () => {},
- addRelation: () => {},
- addRepeatableComponentToField: () => {},
- moveComponentDown: () => {},
- moveComponentField: () => {},
- moveComponentUp: () => {},
- moveRelation: () => {},
- onChange: () => {},
- onRemoveRelation: () => {},
- removeComponentFromDynamicZone: () => {},
- removeComponentFromField: () => {},
- removeRepeatableField: () => {},
- } = useCMEditViewDataManager()
-
- return null
-}
-```
-
-
-
-### Reducers API
-
-Reducers are reducers that can be used to share state between components. Reducers can be useful when:
-
-* Large amounts of application state are needed in many places in the application.
-* The application state is updated frequently.
-* The logic to update that state may be complex.
-
-Reducers can be added to a plugin interface with the `addReducers()` function during the [`register`](#register) lifecycle.
-
-A reducer is declared as an object with this syntax:
-
**Example:**
```js title="my-plugin/admin/src/index.js"
-
-const reducers = {
- // Reducer Syntax
- [`${pluginId}_exampleReducer`]: exampleReducer
-}
-
- register(app) {
- app.addReducers(reducers)
- },
- bootstrap() {},
-};
-
-```
-
-### Hooks API
-
-The Hooks API allows a plugin to create and register hooks, i.e. places in the application where plugins can add personalized behavior.
-
-Hooks should be registered during the [bootstrap](#bootstrap) lifecycle of a plugin.
-
-Hooks can then be run in series, in waterfall or in parallel:
-
-* `runHookSeries` returns an array corresponding to the result of each function executed, ordered
-* `runHookParallel` returns an array corresponding to the result of the promise resolved by the function executed, ordered
-* `runHookWaterfall` returns a single value corresponding to all the transformations applied by the different functions starting with the initial value `args`.
-
-
-Example: Create a hook in a plugin and use it in another plugin
-
-```jsx title="my-plugin/admin/src/index.js"
-// Create a hook in a plugin
-
- register(app) {
- app.createHook('My-PLUGIN/MY_HOOK');
- }
-}
+// Auto-generated component
```
-```jsx title="my-other-plugin/admin/src/index.js"
-// Use the hook in another plugin
-
- bootstrap(app) {
- app.registerHook('My-PLUGIN/MY_HOOK', (...args) => {
- console.log(args)
-
- // important: return the mutated data
- return args
- });
-
- app.registerPlugin({...})
- }
-}
-```
-
-
-
-#### Predefined hooks
-
-Strapi includes a predefined `Admin/CM/pages/ListView/inject-column-in-table` hook that can be used to add or mutate a column of the List View of the [Content Manager](/cms/intro):
-
-```jsx
-runHookWaterfall(INJECT_COLUMN_IN_TABLE, {
- displayedHeaders: ListFieldLayout[],
- layout: ListFieldLayout,
-});
-```
-
-```tsx
-interface ListFieldLayout {
- /**
- * The attribute data from the content-type's schema for the field
- */
- attribute: Attribute.Any | { type: 'custom' };
- /**
- * Typically used by plugins to render a custom cell
- */
- cellFormatter?: (
- data: Document,
- header: Omit,
- { collectionType, model }: { collectionType: string; model: string }
- ) => React.ReactNode;
- label: string | MessageDescriptor;
- /**
- * the name of the attribute we use to display the actual name e.g. relations
- * are just ids, so we use the mainField to display something meaninginful by
- * looking at the target's schema
- */
- mainField?: string;
- name: string;
- searchable?: boolean;
- sortable?: boolean;
-}
-
-interface ListLayout {
- layout: ListFieldLayout[];
- components?: never;
- metadatas: {
- [K in keyof Contracts.ContentTypes.Metadatas]: Contracts.ContentTypes.Metadatas[K]['list'];
- };
- options: LayoutOptions;
- settings: LayoutSettings;
-}
-
-type LayoutOptions = Schema['options'] & Schema['pluginOptions'] & object;
-
-interface LayoutSettings extends Contracts.ContentTypes.Settings {
- displayName?: string;
- icon?: never;
-}
-```
-
-Strapi also includes a `Admin/CM/pages/EditView/mutate-edit-view-layout` hook that can be used to mutate the Edit View of the [Content Manager](/cms/intro):
-
-```tsx
-interface EditLayout {
- layout: Array>;
- components: {
- [uid: string]: {
- layout: Array;
- settings: Contracts.Components.ComponentConfiguration['settings'] & {
- displayName?: string;
- icon?: string;
- };
- };
- };
- metadatas: {
- [K in keyof Contracts.ContentTypes.Metadatas]: Contracts.ContentTypes.Metadatas[K]['edit'];
- };
- options: LayoutOptions;
- settings: LayoutSettings;
-}
-
-interface EditFieldSharedProps extends Omit {
- hint?: string;
- mainField?: string;
- size: number;
- unique?: boolean;
- visible?: boolean;
-}
-
-/**
- * Map over all the types in Attribute Types and use that to create a union of new types where the attribute type
- * is under the property attribute and the type is under the property type.
- */
-type EditFieldLayout = {
- [K in Attribute.Kind]: EditFieldSharedProps & {
- attribute: Extract;
- type: K;
- };
-}[Attribute.Kind];
-
-type LayoutOptions = Schema['options'] & Schema['pluginOptions'] & object;
-
-interface LayoutSettings extends Contracts.ContentTypes.Settings {
- displayName?: string;
- icon?: never;
-}
-```
-
-:::note
-`EditViewLayout` and `ListViewLayout` are parts of the `useDocumentLayout` hook (see ).
-:::
-
# Content Manager APIs
diff --git a/docusaurus/static/llms.txt b/docusaurus/static/llms.txt
index 3a45d4f89b..b51f02446d 100644
--- a/docusaurus/static/llms.txt
+++ b/docusaurus/static/llms.txt
@@ -101,7 +101,7 @@
- [Breaking changes](https://docs.strapi.io/cms/migration/v4-to-v5/breaking-changes): View the list of all breaking changes introduced between Strapi v4 and v5.
- [Upgrading to Strapi 5 - Introduction and FAQ](https://docs.strapi.io/cms/migration/v4-to-v5/introduction-and-faq): Learn more about how to upgrade to Strapi 5
- [Step-by-step guide to upgrade to Strapi 5](https://docs.strapi.io/cms/migration/v4-to-v5/step-by-step): Follow this step-by-step guide to upgrade from Strapi v4 to Strapi 5
-- [Admin Panel API](https://docs.strapi.io/cms/plugins-development/admin-panel-api): A Strapi plugin can interact with both the [back end](/cms/plugins-development/server-api) and the front end of a Strapi application. The Admin Panel ...
+- [Admin Panel API](https://docs.strapi.io/cms/plugins-development/admin-panel-api): Strapi provides a flexible and extensible admin panel that can be customized through plugins. This documentation outlines how to enhance the Strapi ad...
- [Content Manager APIs](https://docs.strapi.io/cms/plugins-development/content-manager-apis): The Content Manager APIs reference lists the APIs available to plugins for adding actions and options to the Content Manager List view and Edit view.
- [Plugin creation & setup](https://docs.strapi.io/cms/plugins-development/create-a-plugin): Learn how to use the Plugin SDK to build and publish a Strapi plugin
- [Developing plugins](https://docs.strapi.io/cms/plugins-development/developing-plugins): Generation introduction about Strapi plugins development
diff --git a/node_modules/.yarn-integrity b/node_modules/.yarn-integrity
new file mode 100644
index 0000000000..044a5ddd9e
--- /dev/null
+++ b/node_modules/.yarn-integrity
@@ -0,0 +1,10 @@
+{
+ "systemParams": "darwin-arm64-115",
+ "modulesFolders": [],
+ "flags": [],
+ "linkedModules": [],
+ "topLevelPatterns": [],
+ "lockfileEntries": {},
+ "files": [],
+ "artifacts": {}
+}
\ No newline at end of file
diff --git a/yarn.lock b/yarn.lock
new file mode 100644
index 0000000000..fb57ccd13a
--- /dev/null
+++ b/yarn.lock
@@ -0,0 +1,4 @@
+# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
+# yarn lockfile v1
+
+