Analyze an existing Backstage frontend plugin and generate the RHDH dynamic plugin wiring configuration.
- User has an existing Backstage frontend plugin
- User wants to deploy it to RHDH as a dynamic plugin
- User needs the wiring configuration for
dynamic-plugins.yaml
The plugin directory must contain:
package.jsonwith plugin metadatasrc/plugin.tsorsrc/plugin.tsxwith plugin definitionsrc/index.tsexporting plugin components
Find and read:
package.json— Get package namesrc/plugin.tsorsrc/plugin.tsx— Find exported extensionssrc/index.ts— Find public exportsdist-dynamic/dist-scalprum/plugin-manifest.json— Get scalprum name if built
- If
plugin-manifest.jsonexists: Use thenamefield - If
scalpruminpackage.json: Usescalprum.name - Otherwise derive from package name:
@my-org/backstage-plugin-foo→my-org.backstage-plugin-foo@internal/backstage-plugin-foo→internal.backstage-plugin-foo- Unscoped packages: use as-is (no dot transformation)
Analyze plugin source for:
Routable Extensions (pages):
- Look for
createRoutableExtensioninplugin.ts - These become
dynamicRoutesentries
Entity Cards/Content:
- Look for
createComponentExtensioninplugin.ts - These become
mountPointsentries - Check if they use
useEntity(entity-scoped)
API Factories:
- Look for
createApiFactoryandcreateApiRef - These become
apiFactoriesentries
Icons:
- Look for icon exports (React components returning SVG/Icon)
- These become
appIconsentries
Output complete wiring configuration in YAML:
dynamicPlugins:
frontend:
<scalprum-name>:
dynamicRoutes:
- path: /<plugin-id>
importName: <PageComponentName>
menuItem:
icon: <icon-name>
text: <Plugin Display Name>
mountPoints:
- mountPoint: entity.page.overview/cards
importName: <CardComponentName>
config:
if:
allOf:
- isKind: component
apiFactories:
- importName: <apiRefName>
appIcons:
- name: <iconName>
importName: <IconComponentName>Show:
- The YAML configuration block
- A table explaining each entry and its source
- Notes about optional configurations
- Ask if it should be saved to a file
For a plugin with package @internal/backstage-plugin-demoplugin, page DemopluginPage, and API todoApiRef:
dynamicPlugins:
frontend:
internal.backstage-plugin-demoplugin:
dynamicRoutes:
- path: /demoplugin
importName: DemopluginPage
menuItem:
icon: extension
text: Demo Plugin
apiFactories:
- importName: todoApiRefdynamicRoutes:
- path: /my-plugin
importName: MyPluginPage
menuItem:
icon: extension
text: My PluginmountPoints:
- mountPoint: entity.page.overview/cards
importName: MyEntityCard
config:
if:
allOf:
- isKind: componentdynamicRoutes:
- path: /my-plugin
importName: MyPluginPage
menuItem:
icon: myIcon
text: My Plugin
mountPoints:
- mountPoint: entity.page.overview/cards
importName: MyEntityCard
appIcons:
- name: myIcon
importName: MyIcon| Option | Purpose |
|---|---|
dynamicRoutes |
Full page routes with optional sidebar |
mountPoints |
Entity page cards, tabs, integrations |
menuItems |
Sidebar ordering and nesting |
appIcons |
Custom icons |
routeBindings |
External route bindings between plugins |
apiFactories |
Utility API registrations |
entityTabs |
New tabs on entity pages |
scaffolderFieldExtensions |
Custom scaffolder form fields |
techdocsAddons |
TechDocs extensions |
themes |
Light/dark theme providers |
signInPage |
Custom auth sign-in page |
providerSettings |
Auth provider settings in preferences |
For complete details on each option, read frontend-wiring.md (in this directory).
For entity page customization patterns, read entity-page.md (in this directory).