Entity Presentation
The Entity Presentation API controls how catalog entities are displayed
throughout the Backstage interface. Instead of rendering raw entity refs like
component:default/my-service, the API resolves a human-friendly display
name from fields such as metadata.title and spec.profile.displayName.
Displaying entity names
There are several ways to display entity names, depending on context:
EntityDisplayName component
The simplest option for React components. Renders a styled entity name with an optional icon and tooltip:
import { EntityDisplayName } from '@backstage/plugin-catalog-react';
<EntityDisplayName entityRef="component:default/my-service" />;
You can pass an entity ref string, an Entity object, or a
CompoundEntityRef. The component supports optional hideIcon and
disableTooltip props.
useEntityPresentation hook
Use this hook when you need access to the raw presentation data in a React component, for example to render the title in a custom layout:
import { useEntityPresentation } from '@backstage/plugin-catalog-react';
function MyComponent({ entityRef }: { entityRef: string }) {
const { primaryTitle, secondaryTitle, Icon } =
useEntityPresentation(entityRef);
return (
<span>
{Icon && <Icon fontSize="inherit" />}
{primaryTitle}
</span>
);
}
The hook subscribes to the EntityPresentationApi and returns a snapshot
that may update over time as additional data is fetched in the background.
Using the API directly (async, preferred for non-React)
In non-React async contexts where you can await -- such as data
loaders, useAsync callbacks, or event handlers -- use the
entityPresentationApiRef API directly with .promise for the richest
possible presentation:
const presentation = await entityPresentationApi.forEntity(entity, {
defaultKind: 'group',
}).promise;
const title = presentation.primaryTitle;
The .promise path resolves to a full presentation that may include data
fetched from the catalog. This is the preferred approach whenever an
async context is available.
entityPresentationSnapshot helper (synchronous fallback)
When a synchronous return value is required and await is not possible --
such as in sort comparators, column factories, or filter callbacks -- use
entityPresentationSnapshot as a fallback. It accepts Entity,
CompoundEntityRef, or string ref inputs and uses the presentation API
when available, falling back to defaultEntityPresentation otherwise:
import {
entityPresentationSnapshot,
entityPresentationApiRef,
} from '@backstage/plugin-catalog-react';
// In a column factory or sort comparator where you have
// the API instance (or undefined if not registered):
const title = entityPresentationSnapshot(
entity,
{
defaultKind: 'Component',
},
entityPresentationApi,
).primaryTitle;
Because this function is synchronous, it uses cached data from the presentation API. If the entity has been seen before, the snapshot will contain the full resolved title; otherwise it falls back to what can be extracted from the ref alone.
Customizing entity presentation
To customize how entities are rendered, provide your own implementation of
the EntityPresentationApi interface and register it with the app's API
factory:
import {
entityPresentationApiRef,
type EntityPresentationApi,
} from '@backstage/plugin-catalog-react';
import { createApiFactory } from '@backstage/core-plugin-api';
const myPresentationApi: EntityPresentationApi = {
forEntity(entityOrRef, context) {
// Return an EntityRefPresentation with snapshot, update$, and promise
},
};
createApiFactory({
api: entityPresentationApiRef,
deps: {},
factory: () => myPresentationApi,
});
The presentation snapshot includes primaryTitle, an optional
secondaryTitle for tooltips, and an optional Icon component. You can
also emit updated snapshots over time via the update$ observable.
Migrating from humanizeEntityRef
The humanizeEntityRef and humanizeEntity functions are deprecated. They
only produce a shortened entity ref string and do not resolve display names
from metadata.title or spec.profile.displayName.
Replace them as follows:
| Old code | Replacement |
|---|---|
humanizeEntityRef(entity) in JSX | <EntityDisplayName entityRef={entity} /> |
humanizeEntityRef(entity) in a React component | useEntityPresentation(entity).primaryTitle |
humanizeEntityRef(entity) in an async loader | (await entityPresentationApi.forEntity(entity).promise).primaryTitle |
humanizeEntityRef(entity) in a sort/filter callback | entityPresentationSnapshot(entity, ctx, api).primaryTitle |
humanizeEntity(entity, fallback) | useEntityPresentation(entity).primaryTitle |