This article is a continuation of the following content: Generate a plugin part 1/6
When creating a plugin, this is what Strapi will generate for you in the ./src/plugins/your-plugin-folder
:
1├── README.md // You know...
2├── admin // Front-end of your plugin.
3│ └── src
4│ ├── components // Contains your front-end components.
5│ │ ├── Initializer
6│ │ │ └── index.js // Plugin initializer.
7│ │ └── PluginIcon
8│ │ └── index.js // Contains the icon of your plugin in the main navigation.
9│ ├── index.js // Main configurations of your plugin.
10│ ├── pages // Contains the pages of your plugin.
11│ │ ├── App
12│ │ │ └── index.js // Skeleton around the actual pages.
13│ │ └── HomePage
14│ │ └── index.js // Homepage of your plugin.
15│ ├── pluginId.js // pluginId variable computed from package.json name.
16│ ├── translations // Translations files to make your plugin i18n friendly
17│ │ ├── en.json
18│ │ └── fr.json
19│ └── utils
20│ ├── getTrad.js // getTrad function to return the corresponding plugin translations
21| └── axiosInstance.js // axios with a custom config
22├── package.json
23├── server // Back-end of your plugin
24│ ├── bootstrap.js // Function that is called right after the plugin has registered.
25│ ├── config
26│ │ └── index.js // Contains the default server configuration.
27│ ├── controllers
28│ │ ├── index.js // File that loads all your controllers
29│ │ └── my-controller.js // Default controller, you can rename/delete it
30│ ├── destroy.js // Function that is called to clean up the plugin after Strapi instance is destroyed
31│ ├── index.js
32│ ├── register.js // Function that is called to load the plugin, before bootstrap.
33│ ├── routes
34│ │ └── index.js // Plugin routes, you can update/delete it
35│ └── services
36│ ├── index.js // File that loads all your services
37│ └── my-service.js // Default services, you can rename/delete it
38├── strapi-admin.js // Entrypoint for the admin (front-end)
39└── strapi-server.js // Entrypoint for the server (back-end)
A plugin is divided into two parts: admin and server. It is interesting to know that a plugin can have multiple purposes:
You can create a plugin that will just use the server part to enhance the API of your application. We can think of a plugin that will have its own visible or invisible content-types, controller actions, and routes that are useful for a specific use case. In such a scenario, you don't need your plugin to have a specific interface in the admin.
You can create a plugin just to inject some components into the admin. However, just know that you can basically do this by creating an ./src/admin/app.js
file, invoking the bootstrap lifecycle function to inject your components:
1// ./src/admin/app.js
2import TweetButton from './extensions/components/TweetButton'; // Component displaying a tweet button in the Content Manager
3
4export default {
5 // ...
6 bootstrap(app) {
7 app.injectContentManagerComponent('editView', 'right-links', {
8 name: 'TweetButton',
9 Component: TweetButton,
10 });
11 },
12 // ...
13};
1// ./src/admin/extensions/TweetButton/index.js
2import React from 'react';
3import { Button } from '@strapi/design-system/Button';
4import Twitter from '@strapi/icons/Twitter';
5import { useCMEditViewDataManager } from '@strapi/helper-plugin';
6import { useIntl } from 'react-intl';
7
8const TweetButton = () => {
9 const { formatMessage } = useIntl();
10 const { modifiedData, layout } = useCMEditViewDataManager();
11 const allowedTypes = ['restaurant', 'article'];
12
13 if (!allowedTypes.includes(layout.apiID)) {
14 return <></>;
15 }
16
17 const base = layout.apiID == 'restaurant' ? 'restaurants' : 'blog';
18
19 const handleTweet = () => {
20 const tweetUrl = `https://twitter.com/intent/tweet?text=${`${encodeURIComponent(
21 modifiedData.seo.metaTitle
22 )} (powered by Strapi)`}&url=${process.env.STRAPI_ADMIN_CLIENT_URL}/${base}/${
23 modifiedData.slug
24 }`;
25
26 window.open(tweetUrl, '_blank').focus();
27 };
28
29 const content = {
30 id: 'components.TweetButton.button',
31 defaultMessage: 'Share on Twitter',
32 };
33
34 return (
35 <Button variant="secondary" startIcon={<Twitter />} onClick={handleTweet}>
36 {formatMessage(content)}
37 </Button>
38 );
39};
40
41export default TweetButton;
This is what we are going to do. A plugin that involves some server customization but also a nice interface in the admin. You can find a lot of plugins already on the marketplace.
Next article: Add a content-type to a plugin part 3/6
Maxime started to code in 2015 and quickly joined the Growth team of Strapi. He particularly likes to create useful content for the awesome Strapi community. Send him a meme on Twitter to make his day: @MaxCastres