Simply copy and paste the following command line in your terminal to create your first Strapi project.
npx create-strapi-app
my-project
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
├── README.md // You know...
├── admin // Front-end of your plugin.
│ └── src
│ ├── components // Contains your front-end components.
│ │ ├── Initializer
│ │ │ └── index.js // Plugin initializer.
│ │ └── PluginIcon
│ │ └── index.js // Contains the icon of your plugin in the main navigation.
│ ├── index.js // Main configurations of your plugin.
│ ├── pages // Contains the pages of your plugin.
│ │ ├── App
│ │ │ └── index.js // Skeleton around the actual pages.
│ │ └── HomePage
│ │ └── index.js // Homepage of your plugin.
│ ├── pluginId.js // pluginId variable computed from package.json name.
│ ├── translations // Translations files to make your plugin i18n friendly
│ │ ├── en.json
│ │ └── fr.json
│ └── utils
│ ├── getTrad.js // getTrad function to return the corresponding plugin translations
| └── axiosInstance.js // axios with a custom config
├── package.json
├── server // Back-end of your plugin
│ ├── bootstrap.js // Function that is called right after the plugin has registered.
│ ├── config
│ │ └── index.js // Contains the default server configuration.
│ ├── controllers
│ │ ├── index.js // File that loads all your controllers
│ │ └── my-controller.js // Default controller, you can rename/delete it
│ ├── destroy.js // Function that is called to clean up the plugin after Strapi instance is destroyed
│ ├── index.js
│ ├── register.js // Function that is called to load the plugin, before bootstrap.
│ ├── routes
│ │ └── index.js // Plugin routes, you can update/delete it
│ └── services
│ ├── index.js // File that loads all your services
│ └── my-service.js // Default services, you can rename/delete it
├── strapi-admin.js // Entrypoint for the admin (front-end)
└── 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
2
3
4
5
6
7
8
9
10
11
12
13
// ./src/admin/app.js
import TweetButton from './extensions/components/TweetButton'; // Component displaying a tweet button in the Content Manager
export default {
// ...
bootstrap(app) {
app.injectContentManagerComponent('editView', 'right-links', {
name: 'TweetButton',
Component: TweetButton,
});
},
// ...
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
// ./src/admin/extensions/TweetButton/index.js
import React from 'react';
import { Button } from '@strapi/design-system/Button';
import Twitter from '@strapi/icons/Twitter';
import { useCMEditViewDataManager } from '@strapi/helper-plugin';
import { useIntl } from 'react-intl';
const TweetButton = () => {
const { formatMessage } = useIntl();
const { modifiedData, layout } = useCMEditViewDataManager();
const allowedTypes = ['restaurant', 'article'];
if (!allowedTypes.includes(layout.apiID)) {
return <></>;
}
const base = layout.apiID == 'restaurant' ? 'restaurants' : 'blog';
const handleTweet = () => {
const tweetUrl = `https://twitter.com/intent/tweet?text=${`${encodeURIComponent(
modifiedData.seo.metaTitle
)} (powered by Strapi)`}&url=${process.env.STRAPI_ADMIN_CLIENT_URL}/${base}/${
modifiedData.slug
}`;
window.open(tweetUrl, '_blank').focus();
};
const content = {
id: 'components.TweetButton.button',
defaultMessage: 'Share on Twitter',
};
return (
<Button variant="secondary" startIcon={<Twitter />} onClick={handleTweet}>
{formatMessage(content)}
</Button>
);
};
export 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