Skip to main content
Version: Next

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 codeReplacement
humanizeEntityRef(entity) in JSX<EntityDisplayName entityRef={entity} />
humanizeEntityRef(entity) in a React componentuseEntityPresentation(entity).primaryTitle
humanizeEntityRef(entity) in an async loader(await entityPresentationApi.forEntity(entity).promise).primaryTitle
humanizeEntityRef(entity) in a sort/filter callbackentityPresentationSnapshot(entity, ctx, api).primaryTitle
humanizeEntity(entity, fallback)useEntityPresentation(entity).primaryTitle