-
Notifications
You must be signed in to change notification settings - Fork 0
Add Widgets API documentation and enable unstableWidgetsApi feature flag #3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,124 @@ | ||||||||||
--- | ||||||||||
title: Widgets API | ||||||||||
description: Learn how to use the Widgets API to create and manage widgets in the Strapi admin panel. | ||||||||||
displayed_sidebar: cmsSidebar | ||||||||||
tags: | ||||||||||
- widgets | ||||||||||
- admin panel | ||||||||||
- plugins development | ||||||||||
--- | ||||||||||
|
||||||||||
# Widgets API | ||||||||||
|
||||||||||
The Widgets API allows you to create and manage widgets in the Strapi admin panel. Widgets are customizable components that can be added to various parts of the admin interface to display information or provide additional functionality. | ||||||||||
|
||||||||||
## Creating a Widget | ||||||||||
|
||||||||||
To create a widget, you need to use the `Widgets` class from the `@strapi/admin` package. Here's an example of how to create a widget: | ||||||||||
|
||||||||||
```javascript | ||||||||||
import { Widgets } from '@strapi/admin'; | ||||||||||
|
||||||||||
const widgets = new Widgets(); | ||||||||||
|
||||||||||
widgets.register({ | ||||||||||
id: 'my-widget', | ||||||||||
pluginId: 'my-plugin', | ||||||||||
icon: MyWidgetIcon, | ||||||||||
title: { | ||||||||||
id: 'my-widget.title', | ||||||||||
defaultMessage: 'My Widget', | ||||||||||
}, | ||||||||||
component: () => import('./components/MyWidget'), | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the component function should return a component directly, not a file that has a component as a default export. so:
Suggested change
|
||||||||||
}); | ||||||||||
``` | ||||||||||
|
||||||||||
The `register` method accepts an object with the following properties: | ||||||||||
|
||||||||||
- `id` (string): A unique identifier for the widget. | ||||||||||
- `pluginId` (string, optional): The ID of the plugin if the widget belongs to a specific plugin. | ||||||||||
- `icon` (React.ComponentType): The icon component to display for the widget. | ||||||||||
- `title` (MessageDescriptor): The title of the widget, using React Intl format. | ||||||||||
- `component` (function): A function that returns a Promise resolving to the widget's React component. | ||||||||||
- `permissions` (array, optional): An array of permission objects to control access to the widget. | ||||||||||
|
||||||||||
## Managing Widgets | ||||||||||
|
||||||||||
The `Widgets` class provides methods to manage widgets: | ||||||||||
|
||||||||||
### getAll() | ||||||||||
|
||||||||||
Retrieves all registered widgets: | ||||||||||
|
||||||||||
```javascript | ||||||||||
const allWidgets = widgets.getAll(); | ||||||||||
``` | ||||||||||
Comment on lines
+49
to
+55
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this isn't useful to users, it just allows us to render the homepage. Registering is all that matters for them so I recommend to omit the rest |
||||||||||
|
||||||||||
### register() | ||||||||||
|
||||||||||
Registers one or multiple widgets: | ||||||||||
|
||||||||||
```javascript | ||||||||||
// Register a single widget | ||||||||||
widgets.register({ | ||||||||||
id: 'widget1', | ||||||||||
// ... other properties | ||||||||||
}); | ||||||||||
|
||||||||||
// Register multiple widgets | ||||||||||
widgets.register([ | ||||||||||
{ | ||||||||||
id: 'widget1', | ||||||||||
// ... other properties | ||||||||||
}, | ||||||||||
{ | ||||||||||
id: 'widget2', | ||||||||||
// ... other properties | ||||||||||
}, | ||||||||||
]); | ||||||||||
``` | ||||||||||
|
||||||||||
## Widget UID | ||||||||||
|
||||||||||
Widgets are identified by a unique UID, which is automatically generated based on the `pluginId` and `id`: | ||||||||||
|
||||||||||
- For plugin widgets: `plugin::{pluginId}.{id}` | ||||||||||
- For global widgets: `global::{id}` | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think "global" is clear to users. Basically it's for widgets created directly within an app, not via a plugin There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. But also, users shouldn't care at all about the UID, it's just useful to us to render the homepage |
||||||||||
|
||||||||||
## Best Practices | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this part is quite visibly AI generated imo, most of it is common sense |
||||||||||
|
||||||||||
1. Use meaningful and unique IDs for your widgets to avoid conflicts. | ||||||||||
2. Implement lazy loading for widget components to improve performance. | ||||||||||
3. Use the `permissions` property to control access to widgets based on user roles. | ||||||||||
4. Provide clear and concise titles for widgets to improve user experience. | ||||||||||
5. Use appropriate icons that represent the widget's functionality. | ||||||||||
|
||||||||||
## Example: Creating a Dashboard Widget | ||||||||||
|
||||||||||
Here's an example of how to create a dashboard widget that displays recent content: | ||||||||||
|
||||||||||
```javascript | ||||||||||
import { Widgets } from '@strapi/admin'; | ||||||||||
import RecentContentIcon from './icons/RecentContent'; | ||||||||||
|
||||||||||
const widgets = new Widgets(); | ||||||||||
|
||||||||||
widgets.register({ | ||||||||||
Comment on lines
+101
to
+106
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same comment as before, this isn't how registration works |
||||||||||
id: 'recent-content', | ||||||||||
icon: RecentContentIcon, | ||||||||||
title: { | ||||||||||
id: 'dashboard.widgets.recent-content.title', | ||||||||||
defaultMessage: 'Recent Content', | ||||||||||
}, | ||||||||||
component: () => import('./components/RecentContentWidget'), | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't see the point of this example, it's the same thing as the one above. What would be interesting instead is to show how to build the actual component |
||||||||||
permissions: [ | ||||||||||
{ action: 'plugin::content-manager.explorer.read', subject: 'api::article.article' }, | ||||||||||
], | ||||||||||
}); | ||||||||||
``` | ||||||||||
|
||||||||||
In this example, we create a widget that displays recent content. The widget is only accessible to users who have permission to read articles in the Content Manager. | ||||||||||
|
||||||||||
Remember to implement the `RecentContentWidget` component and define the necessary translations for the widget title. | ||||||||||
|
||||||||||
By using the Widgets API, you can create powerful and customizable widgets to enhance the Strapi admin panel experience for your users. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is wrong, what we should explain instead is: