Tips logo

Backstage Tips Plugin

Created by dweber019

Tips is a Backstage plugin that shows helpful hints right where engineers work. It adds a small dialog on entity pages that surfaces context aware guidance. Each tip has a title, content, and a simple rule that decides when it should appear. You can ship it with the defaults or add your own tips so the advice matches your platform.

The plugin focuses on nudging teams to take the next step. It can point out missing ownership info or catalog data. It can guide a service owner when a relation is broken or processing failed. It can suggest how to add the right annotations or where to find docs. The content supports Markdown, so you can keep tips short and readable.

Typical use cases start with onboarding. New services get gentle prompts that explain standards and how to meet them. Mature teams see reminders that keep data fresh. Platform folks can encode tribal knowledge as tips instead of repeating the same answers in chat. Over time this reduces friction for both sides.

Tips is lightweight. It stays out of the way until a rule says a tip matters. When it shows up, it is specific to the entity at hand. That makes guidance timely and useful without adding noise.

Installation Instructions

These instructions apply to self-hosted Backstage only.

Step 1 Install the package

Copy
yarn --cwd packages/app add @dweber019/backstage-plugin-tips

Step 2 Add the dialog to the entity page

Option A Use the existing entity warning content block

Add the dialog where your entity warnings render. This follows the common Backstage app layout.

Copy
// packages/app/src/components/catalog/EntityPage.tsx

import { EntityTipsDialog } from '@dweber019/backstage-plugin-tips';
// other imports already in your file

const entityWarningContent = (
  <>
    <EntitySwitch>
      <EntitySwitch.Case if={isOrphan}>
        <Grid item xs={12}>
          <EntityOrphanWarning />
        </Grid>
      </EntitySwitch.Case>
    </EntitySwitch>

    <EntitySwitch>
      <EntitySwitch.Case if={hasRelationWarnings}>
        <Grid item xs={12}>
          <EntityRelationWarning />
        </Grid>
      </EntitySwitch.Case>
    </EntitySwitch>

    <EntitySwitch>
      <EntitySwitch.Case if={hasCatalogProcessingErrors}>
        <Grid item xs={12}>
          <EntityProcessingErrorsPanel />
        </Grid>
      </EntitySwitch.Case>
    </EntitySwitch>

    <EntityTipsDialog />
  </>
);

Option B Render the dialog in your overview tab

If your app does not use the entity warning content block, render the dialog inside the overview route.

Copy
// packages/app/src/components/catalog/EntityPage.tsx

import { EntityTipsDialog } from '@dweber019/backstage-plugin-tips';
// other imports already in your file

// inside the EntityLayout for the overview route
<EntityLayout.Route path="/" title="Overview">
  <Grid container spacing={3}>
    {/* your existing overview content */}
    <Grid item xs={12}>
      <EntityTipsDialog />
    </Grid>
  </Grid>
</EntityLayout.Route>

Step 3 Register tips in the app api factory

Add the tips config factory to your app apis. This enables the built in tips. You can append your own tips later.

Copy
// packages/app/src/apis.ts

import { AnyApiFactory, createApiFactory } from '@backstage/core-plugin-api';
import { tipsConfigRef, systemModelTips, extraTips } from '@dweber019/backstage-plugin-tips';

// keep your existing factories
export const apis: AnyApiFactory[] = [
  // ...your existing factories
  createApiFactory({
    api: tipsConfigRef,
    deps: {},
    factory: () => {
      return {
        tips: [...systemModelTips, ...extraTips],
      };
    },
  }),
];

Step 4 Add a custom tip optional

Create a tip that matches the Tip interface. Then include it in the factory from the previous step.

Copy
// packages/app/src/components/tips/YourTip.tsx

import React from 'react';
import { Tip } from '@dweber019/backstage-plugin-tips';
import { Entity } from '@backstage/catalog-model';

export const YourTip: Tip = {
  title: 'Set an owner',
  content:
    'This entity has no owner. Add an owner field to the catalog info file to improve ownership data.',
  activate: ({ entity }: { entity?: Entity }) => {
    return !entity?.spec?.owner;
  },
};

Update your api factory to include the custom tip.

Copy
// packages/app/src/apis.ts

import { AnyApiFactory, createApiFactory } from '@backstage/core-plugin-api';
import { tipsConfigRef, systemModelTips, extraTips } from '@dweber019/backstage-plugin-tips';
import { YourTip } from './components/tips/YourTip';

export const apis: AnyApiFactory[] = [
  // ...your existing factories
  createApiFactory({
    api: tipsConfigRef,
    deps: {},
    factory: () => {
      return {
        tips: [...systemModelTips, ...extraTips, YourTip],
      };
    },
  }),
];

Notes on content rendering

  • If a tip content is a string, the app renders it with the Backstage Markdown component

Changelog

This changelog is produced from commits made to the Tips plugin since a year ago, and based on the code located here. It may not contain information about all commits. Releases and version bumps are intentionally omitted. This changelog is generated by AI.

Maintenance

  • Update Backstage to 1.41.1 #108 merged 2 months ago
  • Update Backstage to 1.41.0 #101 merged 3 months ago
  • Update Backstage to 1.36.1 #92 merged 7 months ago
  • Update Backstage to 1.35.0 #86 merged 9 months ago
  • Update Backstage to 1.34.2 #84 merged 9 months ago
  • Update Backstage dependencies to 1.32.2 #77 merged 11 months ago

Refactors

  • Remove unused React imports in the plugin #101 merged 3 months ago

Breaking changes

  • None

Set up Backstage in minutes with Roadie