Skip to content

Architecture overview 2: Add plugins

Marlo Longley edited this page Aug 29, 2025 · 7 revisions

Add plugins

Add plugins allow React components to be dynamically extended by injecting external components at predefined locations in the component tree.

These are used to insert new UI elements into existing views.

Key elements

  • PluginContext – A React context holding a plugin map for different targets:

    {
      AttributionPanel: {
        add: [
          { component: CustomLicenseNotice }
        ]
      },
      WindowTopBarPluginMenu: {
        add: [
          { component: CustomTopBarMenuItem }
        ]
      }
    } 
  • PluginHook – A utility component that renders the matching add plugins for a given targetName. Uses usePlugins internally for standard rendering of registered plugins.

  • usePlugins(targetName) – A React hook that returns all add plugins registered for a given target component. Use directly in the component if custom rendering is desired.

usePlugins vs <PluginHook />

Mirador provides two ways to render add plugins inside components:

Tool Purpose When to Use
usePlugins() Fetch plugin components from context When you want custom logic or rendering for plugins
<PluginHook /> Automatically render plugin components When you want a quick, standard way to inject plugins

<PluginHook targetName="..." {...props} />

This is a helper component that uses usePlugins internally. It is the way to render all plugins for a given component. It maps over and renders all plugin components for the given targetName and uutomatically injects props and handles plugin rendering.

Example usage link

<PluginHook targetName="AttributionPanel" {...pluginProps} />

usePlugins(targetName)

  • A React hook that retrieves all registered add plugins for the given targetName.
  • Returns an object:
    { PluginComponents: [ComponentA, ComponentB, ...] }

If you need custom or conditional logic beyond what PluginHook does, you can use usePlugins directly in your component.

Example usage link

WindowSideBarButtons directly accesses usePlugins because it wants to do custom things with the attributes of each component:

const { PluginComponents } = usePlugins('WindowSideBarButtons');

return (
  ...
  { PluginComponents
        && PluginComponents.map(PluginComponent => (
          <TabButton
            key={PluginComponent.value}
            value={PluginComponent.value}
            icon={<PluginComponent />}
          />
        ))
    }

Clone this wiki locally