docs: update plugin create and reference docs for top-level routable extensions
This commit is contained in:
@@ -0,0 +1 @@
|
||||
<mxfile host="Chrome" modified="2021-01-03T17:00:54.430Z" agent="5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36" version="13.9.5" etag="DwPjZwigIikbKX1hFX51" type="device"><diagram id="WdRoEH4gdfKcJUWp3sm5" name="Page-1">7VpLc6M4EP41PiaFBLbh6LxmLlubSqZ2Z+amBQVUBYgScmzPrx9hJIMQGJzEhtTOxUaNnp++bnU3mtm3yfYLQ1n0Fw1wPINWsJ3ZdzMIAfQ88VdIdqXEs2EpCBkJZKVK8Ex+YSm0pHRNApxrFTmlMSeZLvRpmmKfazLEGN3o1V5orI+aoRAbgmcfxab0XxLwqJS6cFnJv2ISRmpksJALTpCqLFeSRyigm5rIvp/Zt4xSXj4l21scF+ApXMp2Dx1vDxNjOOVDGvwk7Nv6n4erTfLNgzcr9/HvH5sru+zlFcVrueBVlsn58p0CId+QJEapKN3I+phxvO2cCDgsT/AC0wRzthNVZANXAiIZARayvKnwPdSJathCRwqR3NPw0HW1bPEgV34CCs4gFBhdpwEu+rEEEJuIcPycIb94uxHkF7KIJ2LcOzAUp+4t6QQP6uA5JnZt0J0NOduEzsAtFMBlnXhIxUX/qerWqXxyFv2EsuFFCQVNvbrfcpzmhKb5aMRyjsPo6CgCZ1xqKSbVMHyia46f8MtEEQSuDqEzNoLgsyPYRkLQpsrnw9CA8IHRVKhyIKSP8Tok6buPy7cgBVtsnHVRG2eSqwOOC1ELfqZz05ucZh6HDyygjh8cFz8wPdPWB+C0COga+I3voPRosM5AAMamoNUN4UQRbPjJYGQOgoWBoAGcOGhXRRgvSn6M8pz4OlYByqM9rhVwODBC+iGwiWHpmvl4wJZzxEJ8rMOOgKUG9LwFaCVjOEacvOqLaENfjvBIiVjeYZu9xjZbjf0rlykbwVrCQPWjGtqNhuWyjYb7vT+s8h10WL6fDmKf2e67VLN94UdRuIZzVb7b1t/e7VRpS/h31Yl4rjcTxapVUVCNzs63oXQblW9LnW/eqXRTNs7R+3EvzD7zRJy6R9F/IF42VgKmV1uciCxF8dSh7D8ZLxx2ms7F6baw1aQdt2iFLXuWQ1DGIxpSsXv3lbTTwvYZ2MnYSm9MW3lg1k63ne81lmA+zFoKwqBdrVpWVMiPzLcxzsI6bVq2Vl88lBP4UMsNB+Sga2px+A5j1d3HooBiEqaFNglGYiYEhaUhPopX8kVCgmCvBKKPrOg52YbFZ6/r8ksTLP+LbhXr9x/CgH0t8L1JKfcjKX+JSfb1zFbtqunvt+SMnBaqw7MZtXnr+TDpoLORj3THTumaIdPkIWy4Ke7IcTs0w4xVRibrmzSV2DWV+LLwfb7MEVhMTYvbHeVpYzgxNbZND1mo8QPyOZW9TxDDiemybWbRDeSGRhkqlBgSZczOHAsobvQGA+VZMFqizr2eL4ED3fJ3sdTY8eY8SiMfA5r0OXMiRV3w+rCs7ttj0jdm/ZafI+tnW7MRydtkWTNqGErXnuzhR8WxDTdq2RPHNr0u7wJxrG1eGjIU508cW23GaHEs+N9uVNellJ1uWj5+Y2bFtRt1U7ZUuOq+sX3/Gw==</diagram></mxfile>
|
||||
@@ -23,35 +23,60 @@ browser APIs or by depending on external modules to do the work.
|
||||
|
||||
### Routing
|
||||
|
||||
Each plugin is responsible for registering its components to corresponding
|
||||
routes in the app.
|
||||
Each plugin can export routable extensions, which are then imported into the app
|
||||
and mounted at a path.
|
||||
|
||||
The app will call the `createPlugin` method on each plugin, passing in a
|
||||
`router` object with a set of methods on it.
|
||||
First you will need a `RouteRef` instance to serve as the mount point of your
|
||||
extensions. This can be used within your own plugin to create a link to the
|
||||
extension page using `useRouteRef`, as well as for other plugins to link to your
|
||||
extension.
|
||||
|
||||
```jsx
|
||||
It is best to place these in a separate top-level `src/routes.ts` file, in order
|
||||
to avoid import cycles, for example like this:
|
||||
|
||||
```tsx
|
||||
/* src/routes.ts */
|
||||
import { createRouteRef } from '@backstage/core';
|
||||
|
||||
// Note: This route ref is for internal use only, don't export it from the plugin
|
||||
export const rootRouteRef = createRouteRef({
|
||||
title: 'Example Page',
|
||||
});
|
||||
```
|
||||
|
||||
Now that we have a `RouteRef`, we import it into `src/plugin.ts`, create our
|
||||
plugin instance with `createPlugin`, as well as create and wrap our routable
|
||||
extension using `createRoutableExtension` from `@backstage/core`:
|
||||
|
||||
```tsx
|
||||
/* src/plugin.ts */
|
||||
import { createPlugin, createRouteRef } from '@backstage/core';
|
||||
import ExampleComponent from './components/ExampleComponent';
|
||||
|
||||
export const rootRouteRef = createRouteRef({
|
||||
path: '/new-plugin',
|
||||
title: 'New plugin',
|
||||
});
|
||||
|
||||
export const plugin = createPlugin({
|
||||
id: 'new-plugin',
|
||||
register({ router }) {
|
||||
router.addRoute(rootRouteRef, ExampleComponent);
|
||||
// Create a plugin instance and export this from your plugin package
|
||||
export const examplePlugin = createPlugin({
|
||||
id: 'example',
|
||||
routes: {
|
||||
root: rootRouteRef, // This is where the route ref should be exported for usage in the app
|
||||
},
|
||||
});
|
||||
|
||||
// This creates a routable extension, which are typically full pages of content.
|
||||
// Each extension should also be exported from your plugin package.
|
||||
export const ExamplePage = examplePlugin.provide(
|
||||
createRoutableExtension({
|
||||
// The component needs to be lazy-loaded. It's what will actually be rendered in the end.
|
||||
component: () =>
|
||||
import('./components/ExampleComponent').then(m => m.ExampleComponent),
|
||||
// This binds the extension to this route ref, which allows for routing within and across plugin extensions
|
||||
mountPoint: rootRouteRef,
|
||||
}),
|
||||
);
|
||||
```
|
||||
|
||||
#### `router` API
|
||||
This extension can then be imported and used in the app as follow, typically
|
||||
placed within the top-level `<FlatRoutes>`:
|
||||
|
||||
```typescript
|
||||
addRoute(
|
||||
target: RouteRef,
|
||||
Component: ComponentType<any>,
|
||||
options?: RouteOptions,
|
||||
): void;
|
||||
```tsx
|
||||
<Route route="/any-path" element={<ExamplePage />} />
|
||||
```
|
||||
|
||||
@@ -28,6 +28,7 @@ new-plugin/
|
||||
index.ts
|
||||
plugin.test.ts
|
||||
plugin.ts
|
||||
routes.ts
|
||||
jest.config.js
|
||||
jest.setup.ts
|
||||
package.json
|
||||
@@ -56,26 +57,30 @@ package.json to declare the plugin dependencies, metadata and scripts.
|
||||
In the `src` folder we get to the interesting bits. Check out the `plugin.ts`:
|
||||
|
||||
```jsx
|
||||
import { createPlugin, createRouteRef } from '@backstage/core';
|
||||
import ExampleComponent from './components/ExampleComponent';
|
||||
import { createPlugin, createRoutableExtension } from '@backstage/core';
|
||||
|
||||
export const rootRouteRef = createRouteRef({
|
||||
path: '/new-plugin',
|
||||
title: 'New plugin',
|
||||
});
|
||||
import { rootRouteRef } from './routes';
|
||||
|
||||
export const plugin = createPlugin({
|
||||
id: 'new-plugin',
|
||||
register({ router }) {
|
||||
router.addRoute(rootRouteRef, ExampleComponent);
|
||||
export const examplePlugin = createPlugin({
|
||||
id: 'example',
|
||||
routes: {
|
||||
root: rootRouteRef,
|
||||
},
|
||||
});
|
||||
|
||||
export const ExamplePage = examplePlugin.provide(
|
||||
createRoutableExtension({
|
||||
component: () =>
|
||||
import('./components/ExampleComponent').then(m => m.ExampleComponent),
|
||||
mountPoint: rootRouteRef,
|
||||
}),
|
||||
);
|
||||
```
|
||||
|
||||
This is where the plugin is created and where it hooks into the app by declaring
|
||||
what component should be shown on what URL. See reference docs for
|
||||
[createPlugin](../reference/createPlugin.md) or
|
||||
[router](../reference/createPlugin-router.md).
|
||||
This is where the plugin is created and where it creates and exports extensions
|
||||
that can be imported and used the app. See reference docs for
|
||||
[createPlugin](../reference/createPlugin.md) or introduction to the new
|
||||
[Composability System](./composability.md).
|
||||
|
||||
## Components
|
||||
|
||||
@@ -91,12 +96,15 @@ You may tweak these components, rename them and/or replace them completely.
|
||||
|
||||
## Connecting the plugin to the Backstage app
|
||||
|
||||
There are two things needed for a Backstage app to start making use of a plugin.
|
||||
There are three things needed for a Backstage app to start making use of a
|
||||
plugin.
|
||||
|
||||
1. Add plugin as dependency in `app/package.json`
|
||||
2. `import` plugin in `app/src/plugins.ts`
|
||||
3. Import and use one or more plugin extensions, for example in
|
||||
`app/src/App.tsx`.
|
||||
|
||||
Luckily these two steps happen automatically when you create a plugin with the
|
||||
Luckily these three steps happen automatically when you create a plugin with the
|
||||
Backstage CLI.
|
||||
|
||||
## Talking to the outside world
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
---
|
||||
id: createPlugin-router
|
||||
title: createPlugin - router
|
||||
description: Documentation on createPlugin - router
|
||||
---
|
||||
|
||||
The router that is passed to the `register` function makes it possible for
|
||||
plugins to hook into routing of the Backstage app and provide the end users with
|
||||
new views to navigate to. This is done by utilising the following methods on the
|
||||
`router`:
|
||||
|
||||
```typescript
|
||||
addRoute(
|
||||
target: RouteRef,
|
||||
Component: ComponentType<any>,
|
||||
options?: RouteOptions,
|
||||
): void;
|
||||
```
|
||||
|
||||
## RouteRef
|
||||
|
||||
`addRoute` method is using mutable RouteRefs, which can be created as following:
|
||||
|
||||
```ts
|
||||
import { createRouteRef } from '@backstage/core';
|
||||
|
||||
const myPluginRouteRef = createRouteRef({
|
||||
path: '/my-plugin',
|
||||
title: 'My Plugin',
|
||||
});
|
||||
```
|
||||
@@ -17,32 +17,24 @@ type PluginConfig = {
|
||||
};
|
||||
|
||||
type PluginHooks = {
|
||||
router: RouterHooks;
|
||||
featureFlags: FeatureFlagsHooks;
|
||||
};
|
||||
```
|
||||
|
||||
- [Read more about the router here](createPlugin-router.md)
|
||||
- [Read more about feature flags here](createPlugin-feature-flags.md)
|
||||
|
||||
## Example Uses
|
||||
|
||||
### Creating a basic plugin
|
||||
|
||||
Showcasing adding a route and a feature flag.
|
||||
Showcasing adding a feature flag.
|
||||
|
||||
```jsx
|
||||
import { createPlugin, createRouteRef } from '@backstage/core';
|
||||
import ExampleComponent from './components/ExampleComponent';
|
||||
|
||||
export const rootRouteRef = createRouteRef({
|
||||
path: '/new-plugin',
|
||||
title: 'New Plugin',
|
||||
});
|
||||
import { createPlugin } from '@backstage/core';
|
||||
|
||||
export default createPlugin({
|
||||
id: 'new-plugin',
|
||||
register({ router, featureFlags }) {
|
||||
router.addRoute(rootRouteRef, ExampleComponent);
|
||||
featureFlags.register('enable-example-component');
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user