Building a Custom Strapi v5 Plugin for Admin Panel
Introduction
Strapi v5 plugins extend the admin panel with custom functionality using the Plugin SDK. This guide covers creating, developing, and integrating a plugin that works exactly like built-in plugins or 3rd-party plugins from the Marketplace.
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);
},
});
Summary
Creating a custom Strapi v5 plugin involves using the Plugin SDK, defining server logic with the Server API, and extending the admin UI with the Admin Panel API. This provides tailored CMS features without modifying core code and allows for both local use and Marketplace distribution.