creating-backstage-entity-page-extension について
Backstage のカタログエンティティページにカードや専用タブを追加する開発スキルです。ブループリントの選択、エンティティによる絞り込み、単独開発やスキャフォールド後の実装を扱います。
主な機能
- 01エンティティの概要ページにカードを追加
- 02専用ルートを持つエンティティタブを作成
- 03エンティティ属性による拡張機能の絞り込み
- 04コード分割に向けたコンポーネントの非同期読み込み
- 05エンティティコンテキストを使ったデータ取得
活用シーン
- 01カタログエンティティに Jira プロジェクト情報を表示
- 02コンポーネントページにインシデントタブを追加
- 03拡張機能を指定したエンティティ種別に限定
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ vinzscam/ backstage-skills --skill creating-backstage-entity-page-extensionインストール後、Claude Code で/creating-backstage-entity-page-extensionを入力して読み込まれたか確認します。
同梱ファイルreferences/card.mdreferences/content.md
詳細
カタログエンティティページ拡張の作成
このスキルを使用する場面
- カタログエンティティの Overview タブにカードを追加する場合(例:「Jira プロジェクトに関連付けられたコンポーネントに Jira プロジェクト情報を表示する」)
- カタログエンティティページに独自の URL パスを持つコンテンツパネル、つまり タブ 全体を追加する場合(例:コンポーネントのインシデントを一覧表示する、コンポーネント上の「/incidents」タブ)
- エンティティの種類、スペックタイプ、アノテーションの有無、またはカスタム述語に基づいて、拡張機能の表示条件を設定する場合
これは、frontend-plugin-module をスキャフォールドする最も一般的な理由です。作成するプラグインは、これらのブループリントを通じてホストのカタログプラグインを拡張します。
適切なパターンを選ぶ
| 作成するもの | パターン | リファレンス |
|---|---|---|
| エンティティの Overview タブ上のカード | EntityCardBlueprint.make({ name, params: { loader, filter?, type? } }) | references/card.md |
| エンティティページ上の完全なタブ(独自の URL パス) | EntityContentBlueprint.make({ name, params: { path, title, loader, filter?, group?, icon? } }) | references/content.md |
どちらのブループリントも @backstage/plugin-catalog-react/alpha から取得できます。共通点は次のとおりです。
- レンダリングするコンポーネントをコード分割するための
loader: () => Promise<JSX.Element>。 - 拡張機能を表示する条件を制御する
filterパラメーター(下記の「エンティティのフィルタリング」を参照)。 - コンポーネントはカタログエンティティのコンテキスト内でレンダリングされます。
@backstage/plugin-catalog-reactのuseEntity()を使って現在のエンティティを読み取ります。
2 つの呼び出しモード
- スタンドアロン:カタログを対象とする既存の
frontend-plugin-moduleを編集します。適切なリファレンス(カードまたはコンテンツ)を選び、拡張機能を追加します。 - スキャフォールド後(
catalogを対象とするfrontend-plugin-moduleテンプレートでcreating-backstage-pluginから呼び出される場合):ユーザーが説明した拡張機能と、それらがレンダリングするコンポーネントをスキャフォールドします。
エンティティのフィルタリング
両方のブループリントの filter パラメーターによって、拡張機能を適用するエンティティを決定します。次の 3 つの形式を使用できます。
- 文字列(最も一般的):
'kind:component'、'kind:component,spec.type:service'、'metadata.annotations.acme.com/jira-project'。AND 条件にはカンマ区切りを使い、同じキーの複数の形式は OR 条件になります。 FilterPredicate(構造化形式):より複雑なロジックを記述できる、Zod で検証されるオブジェクト形式です。正確な形式は../backstage/packages/filter-predicates/src/を参照して確認してください。- 関数:
(entity: Entity) => boolean— プログラムによる完全な制御が可能です。使用は控えめにしてください。文字列フィルターのほうが、上流の設定オーバーライドシステムと組み合わせやすいためです。
filter を省略すると、すべてのエンティティの種類で拡張機能が表示されます。ほぼ常に誤りとなるため、'kind:component' だけの場合でもフィルターを設定してください。
よくある注意点
- ブループリントは
@backstage/plugin-catalog-react/alpha(現在は@alpha)から提供されます。インポートパスは../backstage/plugins/catalog-react/src/alpha/blueprints/と照らし合わせて確認してください。 - コンポーネント自体は
@backstage/plugin-catalog-react(/alphaではなくメインエントリー)からuseEntityをインポートします。このフックはEntity型の{ entity }を返します。metadataやspecなどに型安全にアクセスするには、@backstage/catalog-modelのカタログエンティティモデルを使用してください。 useEntityは、これらのブループリントのいずれかによってレンダリングされたコンポーネント内でのみ動作します。カタログエンティティのコンテキスト外で呼び出すと、エラーが発生します。- コード分割には
loader: () => Promise<JSX.Element>の形式が必須です。同期的なコンポーネントのインポートを渡さず、() => import('./MyCard').then(m => <m.MyCard />)を使用してください。 - エンティティ固有のデータを取得するには、
useEntityと、using-backstage-frontend-systemのデータフックの規約(useAsyncでfetchApi.fetchをラップするフック)を組み合わせます。キャッシュキーとしてentity.metadata.nameまたはアノテーションを渡してください。 - ホストアプリのカタログプラグインが、カードをアタッチするルート
entity-content:catalog/overviewと、コンテンツタブをアタッチするルートpage:catalog/entityを所有します。モジュールはカタログプラグインと同じバックエンドにインストールします。利用者はbackend.add(...)とapp.installPlugin(...)でインストールでき、それ以外に必要な作業はありません。
コメント
Markdown 対応