Strapi: How to create a set of components and inject them to Strapi Admin website?

exFabrica
5 min readApr 25, 2022

--

Welcome back!

It’s time to find out how we’re going to use everything we’ve built! This story aims to create components to inject in Strapi UI. To do that, we can use the injection zone API from Strapi team. You can find some extra information with on Strapi documentation:

To resume:

Strapi zones injection

Ok, this is the theory, let’s start with the creation of our two useful components:

  1. “Injector” component: the responsibility of this first component is to get all dedicated contextual helps for a document and inject the decorator component (see below) in it.
  2. “Decorator” component: the goal of this one is to build/render the contextual helps entities and display them into the document page. We choose decorator because of decorator design pattern. We want to add new functionalities to the document without updating the original code of Strapi Admin Website. This component will remain totally autonomous.

Go inside “api/src/plugins/awesome-help/admin/src/components” and create a new folder “Injected”. Inside create three new files:

  1. « strapi-list-zone-item.js »: the injector component.
  2. « strapi-ui-decorator.js » : the decorator component.
  3. « strapi-tooltip.css » : the css file associated with tooltip rendering.

Injector Component

In « strapi-list-zone-item.js », put the code bellow:

The “useCMEditViewDataManager” comes from Strapi helper plugin. This object is the current context of loaded document. It’s a REACT hook:

Definition from Strapi Doc:

Once an injection zone is defined, the component to be injected in the Content Manager can have access to all the data of the Edit View through the useCMEditViewDataManager React hook.

useCMEditViewDataManager code

For example, in this component we use the “slug” property from “useCMEditViewDataManager” to get the current document Content-Type.

We also created a REACT state hook to store contextual helps from “Help” API call through “Help” proxy.

The component contains a <Box> element to show a panel in right link list. A <Switch> allows to enable or disable the contextual help. This property is also linked to settings “enabled”.

Finally, if “Help” API returns results, we used a <Portal> component to inject our decorator component.

REACT Portal is a component to render child components into a DOM node outside of the parent DOM hierarchy defined by the component tree hierarchy. Perfect for our decorator component!

Decorator component

In “ strapi-ui-decorator.js”, put the code bellow:

To be totally autonomous, this component uses its own rendering behavior. To build it, we used:

1. a “setInterval” (on each 500ms) function to observe length of labels tags “innerText” in page (because Strapi UI uses partial loading), we need to know if new label tags are loaded. Notice the return of “useEffect” hook to clear the interval when the component is unmounted (prevents memory leak).

2. An another “useEffect” hook to observe “modifiedData” (contains all current document data) object from “useCMEditViewDataManager” context to know if new data was loaded or updated from Strapi.

With two functions, we can predict if the current page has changed. In this case, we use “htmlLookup” function to search, find and build tooltip for a new spotted label. “htmlLookup” is divided in two functions :

  • “createTooltip” creates the tooltip in targeted label tag. A condition test allows to not recreate the span tag each time the “htmlLookup” is used. Thereby, the span tag that contains the tooltip is only created once (notice the “querySelectorAll” request). The structure of tooltip is very simple: Only one span tag containing an Emoji (&#x1F916;) and another span tag itself containing the helpContent property of the “Help” entity. Tooltip behaviors are managed by the associated CSS.
  • “createTooltipInZone”: this function is more complex, because of inner structure of Strapi zone component. We have two cases: one to find the field directly in component in zone and another when the field is in nested component inside a component inside the zone.

Injection

Our two components are ready to be used. We need to inject “StrapiListZoneItem” in the Strapi injected zone. Open “api/src/plugins/awesome-help/admin/src/index.js”.

Replace the bootstrap function with this one:

The plugin boostrap function

We use the function “injectContentManagerComponent” to inject “StrapiListZoneItem” into the component “EditView” in “right-links” zone. Easy!

It’s time to test all process but before we need to make a last change to “HomePage” component.

The goal? Automate Strapi structure change detection. Look at the updated code:

Updated homepage

We removed the scan button, warning panel and update the “useEffect” hook to parse the Strapi structure each time the component is mounted. Now, the plugin automatically reflects Strapi structure updates.

It’s time to test!

Open the “Awesome Help” plugins UI, choose a field and edit the row to add contextual help content.

We replaced TextInput by TextArea to input text on multiple lines

Go to “Content-Manager”, in article, select an article and open it!

Help is here!

Look at the title label, you will find a question mark! Hover it and enjoy!

Tootip in action!

Return to “Awesome Help” and search a more complex field, like “api::article.article/blocks/faq/faq/question” for example. Add a contextual help.

Return in “Content manager” article collection. Take the third one in the list and open it.

Open “faq” and “Faq(2)”:

A more complex example

And VOILA! We finished the plugin! If you’ve read this far, thank you!

Mission complete!

We finalize the “Awesome help” plugin; it’s publication time on Strapi Marketplace! We can think about the next part : How to deploy the plugin?

Back to previous article: How to create a service to manage help documents?

Back to the table of contents: A Strapi V4 plugin from scratch to production

And don’t forget our GIT to get the code: https://github.com/ExFabrica/strapi-stories/tree/develop/part-6

See U!

--

--