diff --git a/docs/assets/techdocs/addon-locations.png b/docs/assets/techdocs/addon-locations.png new file mode 100644 index 0000000000..e535fe61aa Binary files /dev/null and b/docs/assets/techdocs/addon-locations.png differ diff --git a/docs/features/techdocs/README.md b/docs/features/techdocs/README.md index 2ac90f791b..c64d0b785d 100644 --- a/docs/features/techdocs/README.md +++ b/docs/features/techdocs/README.md @@ -76,17 +76,19 @@ TechDocs packages: TechDocs promoted to v1.0! To understand how this change affects the package, please check out our [versioning policy](https://backstage.io/docs/overview/versioning-policy). +**v1.2** 🚧 + +With the Backstage 1.2 release, we plan to introduce the [TechDocs Addon Framework](https://github.com/backstage/backstage/issues/9636) for augmenting the TechDocs experience at read-time. + +In addition to the framework itself, we'll be open sourcing a `` addon, helping you to create a feedback loop that drives up documentation quality and fosters a documentation culture at your organization. + ### **Future work 🔮** Some of the following items are coming soon and some are potential ideas. -- [TechDocs Addon Framework](https://github.com/backstage/backstage/issues/9636) -- Contribute to and deploy from a marketplace of TechDocs Addons -- Addon: Highlight text and raise an Issue to create a feedback loop to drive up documentation quality -- Addon: MDX (allows you to use JSX in your Markdown content) - Better integration with [Scaffolder V2](https://github.com/backstage/backstage/issues/2771) (e.g. easy to choose and plug documentation template with Software Templates) -- Static site generator agnostic +- Static site generator agnostic, including possible support for MDX (allowing you to use JSX in your Markdown content) - Possible to configure several aspects about TechDocs (e.g. URL, homepage, theme) diff --git a/docs/features/techdocs/addons.md b/docs/features/techdocs/addons.md new file mode 100644 index 0000000000..0fba3b92e3 --- /dev/null +++ b/docs/features/techdocs/addons.md @@ -0,0 +1,218 @@ +--- +id: addons +title: TechDocs Addons +description: How to find, use, or create TechDocs Addons. +--- + +> Note: This page contains documentation for features that have not yet been +> released on a [main-line version](https://backstage.io/docs/overview/versioning-policy#main-release-line) +> of Backstage and TechDocs. We plan to make Addons generally available in +> Backstage v1.2. + +## Concepts + +TechDocs is a centralized platform for publishing, viewing, and discovering +technical documentation across an entire organization. It's a solid foundation! +But it doesn't solve higher-order documentation needs on its own: how do you +create and reinforce a culture of documentation? How do you build trust in the +quality of technical documentation? + +TechDocs Addons are a mechanism by which you can customize the TechDocs +experience in order to try and address some of these higher-order needs. + +### Addons + +An Addon is just a react component. Like any react component, it can retrieve +and render data using normal Backstage or native hooks, APIs, and components. +Props can be used to configure its behavior, where appropriate. + +### Locations + +Addons declare a `location` where they will be rendered. Most locations are +representative of physical spaces in the TechDocs UI: + +- `Header`: For Addons which fill up the header from the right, on the same + line as the title. +- `Subheader`: For Addons that sit below the header but above all content. + This is a great location for tooling/configuration of TechDocs display. +- `PrimarySidebar`: Left of the content, above of the navigation. +- `SecondarySidebar`: Right of the content, above the table of contents. +- `Content`: A special location intended for Addons which augment the + statically generated content of the documentation itself. +- `Component`: A [proposed-but-not-yet-implemented](https://github.com/backstage/backstage/issues/11109) + virtual location, aimed at simplifying a common type of Addon. + +TechDocs Addon Location Guide + +### Addon Registry + +The installation and configuration of Addons happens within a Backstage app's +frontend. Addons are imported from plugins and added underneath a registry +component called ``. This registry can be configured for both +the TechDocs Reader page as well as the Entity docs page. + +Addons are rendered in the order in which they are registered. + +## Installing and using Addons + +Addons can be installed and configured in much the same way as extensions for +other Backstage plugins: by adding them underneath an extension registry +component (``) under the route representing the TechDocs Reader +page in your `App.tsx`: + +```tsx +// packages/app/src/App.tsx + +import { TechDocsReaderPage } from '@backstage/plugin-techdocs'; +import { TechDocsAddons } from '@backstage/plugin-techdocs-react/alpha'; +import { ReportIssue } from '@backstage/plugin-techdocs-module-addons-contrib'; + +// ... + +}> + + + {/* Other addons can be added here. */} + +; +``` + +The process for configuring Addons on the documentation tab on the entity page +is very similar; instead of adding the `` registry under a +``, you'd add it as a child of ``: + +```tsx +// packages/app/src/components/catalog/EntityPage.tsx + +import { EntityLayout } from '@backstage/plugin-catalog'; +import { EntityTechdocsContent } from '@backstage/plugin-techdocs'; +import { TechDocsAddons } from '@backstage/plugin-techdocs-react/alpha'; +import { ReportIssue } from '@backstage/plugin-techdocs-module-addons-contrib'; + +// ... + + + + + + {/* Other addons can be added here. */} + + +; +``` + +Note that on the entity page, because the Catalog plugin is responsible for the +page header, TechDocs Addons whose location is `Header` will not be rendered. + +## Available Addons + +Addons can, in principle, be provided by any plugin! To make it easier to +discover available Addons, we've compiled a list of them here: + +| Addon | Package/Plugin | Description | +| ---------------------------------------------------------------------------------------------------------- | -------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [``](https://backstage.io/docs/reference/plugin-techdocs-module-addons-contrib.reportissue) | `@backstage/plugin-techdocs-module-addons-contrib` | Allows TechDocs users to select a portion of text on a TechDocs page and open an issue against the repository that contains the documentation, populating the issue description with the selected text according to a configurable template. | + +Got an Addon to contribute? Feel free to add a row above! + +## Creating an Addon + +The simplest Addons are plain old react components that get rendered in +specific locations within a TechDocs site. To package such a react component as +an Addon, follow these steps: + +1. Write the component in your plugin like any other component +2. Create, provide, and export the component from your plugin + +```ts +// plugins/your-plugin/src/plugin.ts + +import { + createTechDocsAddonExtension, + TechDocsAddonLocations, +} from '@backstage/plugin-techdocs-react/alpha'; +import { CatGifComponent, CatGifComponentProps } from './addons'; + +// ... + +// You must "provide" your Addon, just like any extension, via your plugin. +export const CatGif = yourPlugin.provide( + // This function "creates" the Addon given a component and location. If your + // component can be configured via props, pass the prop type here too. + createTechDocsAddonExtension({ + name: 'CatGif', + location: TechDocsAddonLocations.Header, + component: CatGifComponent, + }), +); +``` + +### Addons in the Content location + +Beyond the "render a component in a region" use-case, it's also possible for +Addons to access and manipulate a TechDocs site's DOM; this could be used to, +for example, load and instantiate client-side diagramming libraries, replace +elements with dynamically loaded content, etc. + +This type of Addon is still expressed as a react component, but instead of +returning a react element to be rendered, it updates the DOM via side-effects +(e.g. with `useEffect`). Access to the DOM is made available via utility hooks +provided by the Addon framework. + +```tsx +// plugins/your-plugin/src/addons/MakeAllImagesCatGifs.tsx + +import React, { useEffect } from 'react'; +import { useShadowRootElements } from '@backstage/plugin-techdocs-react/alpha'; + +// This is a normal react component; in order to make it an Addon, you would +// still create and provide it via your plugin as described above. The only +// difference is that you'd set `location` to `TechDocsAddonLocations.Content`. +export const MakeAllImagesCatGifsAddon = () => { + // This hook can be used to get references to specific elements. If you need + // access to the whole shadow DOM, use the the underlying useShadowRoot() + // hook instead. + const images = useShadowRootElements(['img']); + + useEffect(() => { + images.forEach(img => { + if (img.src !== 'https://example.com/cat.gif') { + img.src = 'https://example.com/cat.gif'; + } + }); + }, [images]); + + // Nothing to render directly, so we can just return null. + return null; +}; +``` + +### Testing Addons + +Install `@backstage/plugin-techdocs-addons-test-utils` as a `devDependency` in +your plugin for access to utilities that make testing such Addons easier. + +A test for the above Addon might look something like this: + +```tsx +// plugins/your-plugin/src/addons/MakeAllImagesCatGifs.test.tsx +import { TechDocsAddonTester } from '@backstage/plugin-techdocs-addons-test-utils'; + +// Note: import your actual addon (the one provided by your plugin). +import { MakeAllImagesCatGifs } from '../plugin.ts'; + +describe('MakeAllImagesCatGifs', () => { + it('replaces img srcs with cat gif', async () => { + const { getByTestId } = await TechDocsAddonTester.buildAddonsInTechDocs([ + , + ]) + .withDom() + .renderWithEffects(); + + expect(getByTestId('fixture')).toHaveAttribute( + 'src', + 'https://example.com/cat.gif', + ); + }); +}); +``` diff --git a/docs/features/techdocs/concepts.md b/docs/features/techdocs/concepts.md index e34f58bc70..c96db5e3b7 100644 --- a/docs/features/techdocs/concepts.md +++ b/docs/features/techdocs/concepts.md @@ -96,10 +96,6 @@ Documentation generated by TechDocs is generated as static HTML sites. The TechDocs Reader was therefore created to be able to integrate pre-generated HTML sites with the Backstage UI. -The TechDocs Reader purpose is also to open up the opportunity to integrate -TechDocs widgets for a customized full-featured TechDocs experience. -([coming soon V.3](./README.md#project-roadmap)) - [TechDocs Reader](https://github.com/backstage/backstage/blob/master/plugins/techdocs/src/reader/README.md) ## Transformers @@ -110,3 +106,19 @@ transform the HTML content on pre and post render (e.g. rewrite docs links or modify css). [Transformers API docs](https://github.com/backstage/backstage/blob/master/plugins/techdocs/src/reader/README.md) + +## TechDocs Addons + +Addons (introduced in Backstage v1.2) are client-side, React-based extensions +that can be used to augment the TechDocs experience at read-time. They offer a +mechanism for configuring the TechDocs Reader to better suit your +organization's needs. + +Addons can dynamically load and display information anywhere in the TechDocs +Reader, including within the statically generated content itself. + +Addons should not be confused with `mkdocs` plugins, which may be used to +customize a TechDocs site's content at build-time. While it's possible to take +advantage of some `mkdocs` plugins, not all such plugins play well with +TechDocs (primarily, but not exclusively, for security reasons). Addons offer +an alternative. diff --git a/microsite/sidebars.json b/microsite/sidebars.json index 81ad453429..43e9dd3978 100644 --- a/microsite/sidebars.json +++ b/microsite/sidebars.json @@ -109,6 +109,7 @@ "features/techdocs/techdocs-overview", "features/techdocs/getting-started", "features/techdocs/concepts", + "features/techdocs/addons", "features/techdocs/architecture", "features/techdocs/creating-and-publishing", "features/techdocs/configuration",