23

My team is creating the administration panel of a CMS using React, Typescript, TSX and Webpack. Each page of the administration panel has been created as a React component, and each page contains many other child components (one for each section).

enter image description here

The CMS distribution currently includes a bundled version of the javascript needed to run the web app, but not the original TSX files.

Now, we would like to make it possible to the developers using our CMS to extend the web app by

1) Injecting additional sections into the UI using a "slot-fill" approach

2) Possibly even overriding the existing sections rendering a different component in the same place.

<div>
  <SidebarComponent />
  <Section1Component />
  <Section2Component />
  // How to inject a  possible PluginComponent here?
</div>

From the research we've conducted so far, there seem to be no "official" way to do this, so I'm wondering what would be the best approach in this case.

tocqueville
  • 5,270
  • 2
  • 40
  • 54
  • 1
    You element may contain a prop to pass an array of plugins. These plugins may be forced to have some hooks your CMS will need to get info from plugin, and these plugins could even have no rendering (if they return null in the render method). – lilezek Jul 27 '17 at 16:21
  • Yeah but how will the plugin developers add their plugins to the array? – tocqueville Jul 27 '17 at 16:23
  • 2
    It could be done by requiring (using `require`) in a plugin folder looking for every `^\.jsx?` file, and then arranging them in the array if there is dependency checking or something similar. – lilezek Jul 27 '17 at 16:34
  • Did you ever come up with a solution here? I found a way to have a plugin concept within the same codebase but delivery outside the codebase by a 3rd party or another team that might manage and own that plugin I found to be a challenge for a web implementation. This (https://www.nylas.com/blog/react-plugins/) had good ideas although it was in electron so it doesn't all carry over. – Lawrence Jan 23 '18 at 22:05
  • 1
    Unfortunately we couldn't find a "react only" solution. We ended up making it possible for the developers to override an entire page using ASP.NET MVC, and inside that page they could use the same react components, which were distributed with the CMS, but passing different props (one of which could be an array of components). Alternatively, they could create new components inheriting from the default ones and overriding their inner members (for example the render method). – tocqueville Jan 24 '18 at 11:02
  • 1
    Is this anything like what you were looking for: https://github.com/camwest/react-slot-fill ? – Garrett Motzner Feb 21 '19 at 01:05

4 Answers4

3

I am facing the same issue where I need a component from a plugin to interact with a component from another plugin with a hook system. I have a created a small codesanbox with the same approach adapted to your need.

Basically the approach is to create a injectedComponents.js at the root of your plugin that specifies in which plugin and area your component needs to be injected.

Here is ademo

soupette
  • 1,260
  • 11
  • 11
3

single-spa has some good options in order to achieve this. Please see if it can be help for you.

Microfrontends

Parcels

Abhinav Singi
  • 3,379
  • 1
  • 20
  • 27
0

I am late to this but Just create a utility class with registry function, and register each component to the registry (just dictionary of key value pair, where key is a constant and Value is the component). T

Then when you display a component in your base app, get it from the registry using a key. Then once you publish this whole base app as package ( make sure to export the utility registry). A user can register a component with the same name and override the default component.

Dan Hunex
  • 5,172
  • 2
  • 27
  • 38
0

For communication between totally independant components, you can use and EventEmitter

  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jan 12 '23 at 05:09