diff --git a/docs/frontend-system/building-plugins/06-swappable-components.md b/docs/frontend-system/building-plugins/06-swappable-components.md index 4c03954bb2..c218c65e56 100644 --- a/docs/frontend-system/building-plugins/06-swappable-components.md +++ b/docs/frontend-system/building-plugins/06-swappable-components.md @@ -22,12 +22,14 @@ export const ExampleSwappableComponent = createSwappableComponent({ // This is a loader for loading the default implementation of the component when there's no overriden // implementation created with `SwappableComponentBlueprint`. - // It can be sync like below, but is can also be async like `loader: () => import('./DefaultImplementation').then(m => m.default)`. + // It can be sync like below, but is can also be async like `loader: () => import('./DefaultImplementation').then(m => m.DefaultImplementation)`. loader: () => (props: { name: string }) =>
Your name is {props.name}
, // This is an optional function that can be used to transform the props of the external component. // If it's not provided, the props of the external component will be passed through unchanged. + // Typically this wouldn't be used and you don't need to define this initially, + // this is a nice API to evolve the Swappable Component internal API without breaking usages of it in existing plugins. transformProps: (props: { lastName: string; firstName: string }) => ({ name: `${props.firstName} ${props.lastName}`, }), @@ -47,34 +49,63 @@ import { ExampleSwappableComponent } from '@internal/plugin-example-react'; ## Overriding a Swappable Component In order to override a Swappable Component, you need to create a `SwappableComponentBlueprint` and install it with the `app` plugin. +There's two different ways to add extensions to the `app` plugin, both are documented below in an example of overriding the `Progress` Swappable Component. ```tsx title="in packages/app/src/App.tsx" -import { ExampleSwappableComponent } from '@internal/plugin-example-react'; - -... - +import { + Progress, + SwappableComponentBlueprint, + createFrontendModule, +} from '@backstage/frontend-plugin-api'; +import { MyCustomProgress } from './CustomProgress'; +import { createApp } from '@backstage/frontend-defaults'; +import appPlugin from '@backstage/plugin-app'; const app = createApp({ features: [ - // Must be installed inside the App Plugin. + // Override an existing extension by ID provided by the app plugin: appPlugin.withOverrides({ extensions: [ - // Create a binding between the original c - SwappableComponentBlueprint.make({ - params: defineParams => defineParams({ - component: ExampleSwappableComponent, - loader: () => import('./ExampleComponent').then(m => m.SwappableComponent), - - // or sync: - // loader: () => MyNewImplementation - }) - }) - ] + appPlugin + .getExtension('component:app/core.components.progress') + .override({ + params: defineParams => + defineParams({ + component: Progress, + loader: () => MyCustomProgress, + }), + }), + ], }), - ... - ] -}) - + // OR: Add another extension but with the same component ID: + appPlugin.withOverrides({ + extensions: [ + SwappableComponentBlueprint.make({ + name: 'core.components.progress', + params: defineParams => + defineParams({ + component: Progress, + loader: () => MyCustomProgress, + }), + }), + ], + }), + // OR: Use a module for the app plugin: + createFrontendModule({ + pluginId: 'app', + extensions: [ + SwappableComponentBlueprint.make({ + name: 'core.components.progress', + params: defineParams => + defineParams({ + component: Progress, + loader: () => MyCustomProgress, + }), + }), + ], + }), + ], +}); ``` ## Default Swappable Components