Strapi v5 plugins use the Plugin SDK to add server routes, admin UI pages, and settings screens. Here’s the skeleton.
Prerequisites
- Strapi v5 project
- Node.js >=18
- Plugin SDK knowledge
Step 1: Create Plugin Using Plugin SDK
cd my-strapi-project
npm create strapi-plugin@latest custom-plugin
This creates plugins/custom-plugin with the proper Strapi v5 structure.
Step 2: Plugin Structure Overview
Strapi v5 plugins have a structured approach with:
- Server API: Backend functionality and routes
- Admin Panel API: Frontend admin interface integration
- Plugin SDK: Tools for development and integration
Step 3: Define Server Entry Point
Edit plugins/custom-plugin/server/index.js:
"use strict";
module.exports = ({ strapi }) => {
return {
async initialize() {
strapi.log.info("Custom Plugin Initialized");
// Register routes
strapi.server.routes([
{
method: "GET",
path: "/custom/hello",
handler: "custom-plugin.hello",
config: { auth: false },
},
]);
},
};
};
Step 4: Add Server Logic
Create plugins/custom-plugin/server/controllers/custom-plugin.js:
"use strict";
module.exports = {
async hello(ctx) {
ctx.body = {
message: "Hello from Strapi v5 custom plugin!",
version: "5.0.0",
};
},
};
Step 5: Extend Admin UI with Admin Panel API
In plugins/custom-plugin/admin/src/index.js:
import pluginPkg from "../../package.json";
export default strapi => {
const pluginName = pluginPkg.strapi.name;
return {
register(app) {
// Add menu link to admin sidebar
app.addMenuLink({
to: `/plugins/${pluginName}`,
icon: "plugin",
intlLabel: {
id: `${pluginName}.plugin.name`,
defaultMessage: "Custom Plugin",
},
Component: async () => {
const component = await import(
/* webpackChunkName: "custom-plugin-page" */ "./pages/App"
);
return component;
},
});
// Add plugin settings
app.addSettingsLink("global", {
intlLabel: {
id: `${pluginName}.plugin.settings`,
defaultMessage: "Custom Plugin Settings",
},
id: "custom-plugin-settings",
to: `/settings/custom-plugin`,
Component: async () => {
const component = await import("./pages/Settings");
return component;
},
});
},
};
};
Create plugins/custom-plugin/admin/src/pages/App/index.js:
import React from "react";
import { request } from "@strapi/helper-plugin";
import { Main, ContentLayout, HeaderLayout } from "@strapi/design-system";
const App = () => {
const [message, setMessage] = React.useState("");
const [loading, setLoading] = React.useState(true);
React.useEffect(() => {
request("/custom/hello", { method: "GET" })
.then(data => {
setMessage(data.message);
setLoading(false);
})
.catch(error => {
console.error("Error fetching data:", error);
setLoading(false);
});
}, []);
return (
<Main>
<HeaderLayout title="Custom Plugin" subtitle="Strapi v5 Plugin Example" />
<ContentLayout>
{loading ? (
<div>Loading...</div>
) : (
<div>
<h3>{message}</h3>
<p>This is a custom plugin page in Strapi v5!</p>
</div>
)}
</ContentLayout>
</Main>
);
};
export default App;
Step 6: Plugin Configuration
Add plugin configuration in config/plugins.js:
module.exports = {
"custom-plugin": {
enabled: true,
config: {
// Plugin-specific configuration
apiKey: process.env.CUSTOM_PLUGIN_API_KEY,
features: ["feature1", "feature2"],
},
},
};
Step 7: Build and Test
Restart Strapi to load the plugin:
npm run develop
Your plugin will appear in the admin sidebar and can be used as a local plugin or submitted to the Marketplace.
Advanced Features
Custom Fields Plugin
Plugins can also be used to add custom fields to Strapi:
module.exports = {
type: "string",
name: "customField",
intlLabel: {
id: "custom-plugin.customField",
defaultMessage: "Custom Field",
},
intlDescription: {
id: "custom-plugin.customField.description",
defaultMessage: "A custom field for your content",
},
};
Data Storage
Store and access data from your plugin:
module.exports = ({ strapi }) => ({
async storeData(data) {
return await strapi.entityService.create("plugin::custom-plugin.data", {
data,
});
},
async getData(id) {
return await strapi.entityService.findOne("plugin::custom-plugin.data", id);
},
});
Server API for the backend, Admin Panel API for the UI, Plugin SDK to tie it together. Works locally or on the Marketplace.