Current version 22.8.0

Migrating from tgBreadcrumbs

Your <ol> and its items stay as they are. The difference is that tg2Breadcrumbs goes on a <nav> around the <ol>, so the breadcrumb is always a labelled navigation landmark.

Checklist

  1. Remove tgBreadcrumbs from the <ol>, and put tg2Breadcrumbs on a <nav> around it. If you already have a <nav> wrapper, add it there.
  2. Replace tgBreadcrumbsItem with tg2BreadcrumbsItem. Your projected <a routerLink> links don't change.
  3. Move any title from the <li> onto its link.
  4. If your trail ends with the current page as plain text, add includesCurrentPage to the <nav>. Leave it off if every item is a link (an ancestors-only trail).
  5. Import Tg2BreadcrumbsComponent and Tg2BreadcrumbsItemComponent instead of TgBreadcrumbsComponent and TgBreadcrumbsItemDirective.
  6. To keep the tgBreadcrumbs look, set data-tg-theme="tg-light" (see below).

Before

  1. Motors
  2. Cars
  3. Toyota

After

<!-- Before -->
<ol tgBreadcrumbs>
    <li tgBreadcrumbsItem><a routerLink="/motors">Motors</a></li>
    <li tgBreadcrumbsItem><a routerLink="/motors/cars">Cars</a></li>
    <li tgBreadcrumbsItem>Toyota</li>
</ol>

<!-- After -->
<nav tg2Breadcrumbs includesCurrentPage>
    <ol>
        <li tg2BreadcrumbsItem><a routerLink="/motors">Motors</a></li>
        <li tg2BreadcrumbsItem><a routerLink="/motors/cars">Cars</a></li>
        <li tg2BreadcrumbsItem>Toyota</li>
    </ol>
</nav>

Why tg2Breadcrumbs goes on the <nav>

A breadcrumb needs both elements, and each does a different job for screen reader users:

  • <nav aria-label="Breadcrumb"> is a landmark. It shows up in the screen reader's landmarks list, so people can jump straight to it.
  • <ol> with <li> items is a list. Screen readers announce its size and each item's position, e.g. "list, 4 items" and "2 of 4", which tells people how deep they are.

With tgBreadcrumbs the <nav> was up to you, and it was easy to leave out. tg2Breadcrumbs is the <nav>, so the landmark is always there. You still write the <ol> and <li> items yourself, so your template stays valid HTML and the list is announced as before. An item that isn't directly inside an <ol> throws an error.

Custom elements such as <tg2-breadcrumbs-item> were ruled out: browsers only treat <li> as list items, so a custom element inside an <ol> breaks the "2 of 4" announcement (NVDA with Firefox in particular).

If you already have a <nav>

Put tg2Breadcrumbs on your existing <nav> rather than adding another one inside it. Two nested navigation landmarks are announced twice. The label defaults to "Breadcrumb", and your own aria-label and classes are kept.

<!-- Before -->
<nav aria-label="Listing location" class="listing__breadcrumbs">
    <ol tgBreadcrumbs>
        <li tgBreadcrumbsItem><a routerLink="/motors">Motors</a></li>
        <li tgBreadcrumbsItem>Toyota</li>
    </ol>
</nav>

<!-- After: tg2Breadcrumbs on your existing <nav>, not a second one inside it -->
<nav tg2Breadcrumbs includesCurrentPage aria-label="Listing location" class="listing__breadcrumbs">
    <ol>
        <li tg2BreadcrumbsItem><a routerLink="/motors">Motors</a></li>
        <li tg2BreadcrumbsItem>Toyota</li>
    </ol>
</nav>

Current page

tgBreadcrumbs never marked the current page, and by default tg2Breadcrumbs doesn't either. Most trails end with the current page as plain text: add includesCurrentPage so the last item gets aria-current="page", which tgBreadcrumbs never set. Leave it off for an ancestors-only trail, where every item is a link and the current page isn't listed. The last item has no separator either way.

<!-- The trail ends with the current page: aria-current="page" goes on the last item -->
<nav tg2Breadcrumbs includesCurrentPage>
    <ol>
        <li tg2BreadcrumbsItem><a routerLink="/motors">Motors</a></li>
        <li tg2BreadcrumbsItem>Toyota</li>
    </ol>
</nav>

<!-- Ancestors only (the default): every item is a link, none is marked -->
<nav tg2Breadcrumbs>
    <ol>
        <li tg2BreadcrumbsItem><a routerLink="/">Home</a></li>
        <li tg2BreadcrumbsItem><a routerLink="/property">Property</a></li>
        <li tg2BreadcrumbsItem><a routerLink="/property/taupaki">Taupaki</a></li>
    </ol>
</nav>

Truncated and title

truncated works as before, and is ignored on the last item. In the tg2 themes a truncated item shows its first 5 characters and "…" rather than "…" alone, and text with fewer than 6 characters isn't truncated. The last item is now capped at 30 characters and "…", with its full text in a title. tg2BreadcrumbsItem has no title input: put a native title on the link instead, which is where the hover happens. If you choose which items to truncate yourself, e.g. by counting characters, set autoTruncate on the <nav> instead: it measures the real widths and adds the title for you.

<!-- Before -->
<li tgBreadcrumbsItem [truncated]="true" title="Vintage bookcases">
    <a routerLink="/furniture/bookcases">Vintage bookcases</a>
</li>

<!-- After: title moves onto the link -->
<li tg2BreadcrumbsItem truncated>
    <a routerLink="/furniture/bookcases" title="Vintage bookcases">Vintage bookcases</a>
</li>

Styling the <ol>

Classes on your <ol> stay where they are. Most only removed the bottom margin tgBreadcrumbs added. tg2Breadcrumbs has no margin (except in the tg-light and tg-dark themes, where it's on the <nav>), so you can usually delete them.

Matching the tgBreadcrumbs look

To keep the tgBreadcrumbs visuals (teal links, a 48px line height, a 2px gap either side of the separator and the bottom margin), set data-tg-theme="tg-light" on the <nav> or any ancestor. See migrating with theme tg-light.

There's no theme input on tg2Breadcrumbs. It follows the nearest data-tg-theme, e.g. on your page's root element.

When not to migrate

Only use tg2Breadcrumbs for the page's own location, once per page. If you used tgBreadcrumbs to show a category path inside a card or list item, switch to plain links: every tg2Breadcrumbs is a navigation landmark.

Proudly made by © 2026 Trade Me Limited