Breadcrumbs
Breadcrumbs are a user interface design pattern that helps users understand their current location within a website or application. They are a navigational aid that displays a hierarchical trail of links from the homepage to the current page. Breadcrumbs are commonly displayed horizontally near the top of the page and use separators (typically chevrons) to indicate hierarchy.
In OpenMRS, breadcrumbs are implemented in the index.ts file using the registerBreadcrumb or registerBreadcrumbs functions exported by the @openmrs/esm-framework package.
The registerBreadcrumb function takes an object with the following properties:
path(required): The URL path of the pagetitle(required): The text that will be displayed in the breadcrumb. This can be a string, a function that returns a string, or a function that returns a Promise resolving to a string. Functions receive route parameters as an argument.parent(optional): The path of the parent breadcrumb to create a hierarchical trailmatcher(optional): A string or RegExp that determines whether the breadcrumb should be displayed. If omitted, thepathvalue is used as the matcher. Useful for dynamic routes with parameters (e.g.,/patient/:patientUuid)
When a user navigates to a registered page, the breadcrumb system automatically displays the appropriate breadcrumb trail based on the current path.
Here is an example of a simple breadcrumb for a page (Core v5+):
import { registerBreadcrumb } from "@openmrs/esm-framework";
export function startupApp() {
registerBreadcrumb({
path: `${window.spaBase}/myPage`,
title: "My First Page",
});
}When a user navigates to /myPage, the breadcrumb will display: My First Page
Breadcrumbs can also represent a trail of hierarchical links from the site homepage to sub pages. To implement this, use the parent property to indicate what should be the parent breadcrumb.
Here is an example of breadcrumbs with ancestors/sub pages (Core v5+):
import { registerBreadcrumbs } from "@openmrs/esm-framework";
export function startupApp() {
registerBreadcrumbs([
{
path: `${window.spaBase}/myPage`,
title: "My First Page",
},
{
path: `${window.spaBase}/myPage/subpage1`,
title: "Subpage 1",
parent: `${window.spaBase}/myPage`,
},
{
path: `${window.spaBase}/myPage/subpage2`,
title: "Subpage 2",
parent: `${window.spaBase}/myPage`,
},
]);
}When a user navigates to different pages, the breadcrumbs will display:
- On
/myPage: My First Page - On
/myPage/subpage1: My First Page > Subpage 1 - On
/myPage/subpage2: My First Page > Subpage 2
Dynamic breadcrumbs with route parameters
You can create dynamic breadcrumbs that use route parameters. The title function receives an array of matched route parameters. For example, to show a patient UUID in the breadcrumb:
import { registerBreadcrumb } from "@openmrs/esm-framework";
export function startupApp() {
registerBreadcrumb({
path: `${window.spaBase}/patient/:patientUuid`,
matcher: `${window.spaBase}/patient/:patientUuid`, // Optional: explicitly define the matcher
title: (params) => {
// params is an array of matched route parameters
// For /patient/:patientUuid, params[0] would be the patientUuid value
return `Patient ${params[0]}`;
},
parent: `${window.spaBase}/patients`,
});
}For more complex scenarios, you can fetch data asynchronously:
import { registerBreadcrumb } from "@openmrs/esm-framework";
export function startupApp() {
registerBreadcrumb({
path: `${window.spaBase}/patient/:patientUuid`,
title: async (params) => {
const patientUuid = params[0];
// Fetch patient data and return the patient name
const patient = await fetchPatient(patientUuid);
return patient.name;
},
parent: `${window.spaBase}/patients`,
});
}Using breadcrumbs in your component
Breadcrumbs are automatically rendered by the app shell as an extension in the breadcrumbs-slot. To display breadcrumbs in your page component, simply include the extension slot:
import { ExtensionSlot } from "@openmrs/esm-framework";
export default function MyPage() {
return (
<>
<ExtensionSlot name="breadcrumbs-slot" />
{/* Your page content */}
</>
);
}The breadcrumbs extension is automatically registered by the app shell, so you don't need to register it yourself. Just include the <ExtensionSlot> component in your page to display the breadcrumb trail.
Breadcrumb behavior
- Breadcrumbs are automatically filtered based on the current path - only breadcrumbs matching the current route are displayed
- The breadcrumb trail follows the parent hierarchy, showing all ancestors up to the current page
- If there are more than 4 breadcrumbs in the trail, the middle ones are collapsed and replaced with "..." to keep the display compact
- Breadcrumb titles that are functions will show a loading indicator while the title is being resolved
- Breadcrumbs are clickable links that navigate to their respective paths