Shoppers can get deep into the tea shop's pages, so each page shows where it is: Home › Shop › Teas › Green. Build Breadcrumbs, a named export of App.jsx, which takes a path like /shop/teas/green. The default export, App, is only for the Preview.
Draw a <nav> with aria-label="Breadcrumb", holding an ordered list (<ol>). The first item is always Home, for /. Then each part of the path gets an item, in order.
Every item except the last is a link to the path up to that part: Home to /, Shop to /shop, Teas to /shop/teas. The last item is the current page: plain text, not a link, with aria-current="page". Each <li> holds only its link or its text (draw any separators with CSS).
Labels are title-cased: hyphens become spaces, and each word starts with a capital letter, with the rest lower case. So loose-leaf is Loose Leaf, and EARL-GREY is Earl Grey. Links use the path parts as they are.
Empty parts are ignored, so a trailing slash or a doubled slash changes nothing: /shop//teas/ is the same as /shop/teas. For /, the only item is Home, as the current page.
<Breadcrumbs path="/shop/teas/green" />
// draws:
<nav aria-label="Breadcrumb">
<ol>
<li><a href="/">Home</a></li>
<li><a href="/shop">Shop</a></li>
<li><a href="/shop/teas">Teas</a></li>
<li><span aria-current="page">Green</span></li>
</ol>
</nav>
render(<Breadcrumbs path="/shop/teas/green" />);
expect(screen.getByRole("navigation", { name: "Breadcrumb" })).toBeInTheDocument();
render(<Breadcrumbs path="/shop/teas/green" />);
const list = within(screen.getByRole("navigation", { name: "Breadcrumb" })).getByRole("list");
expect(list.tagName).toBe("OL");
expect(within(list).getAllByRole("listitem").map((item) => item.textContent)).toEqual(["Home", "Shop", "Teas", "Green"]);
render(<Breadcrumbs path="/shop/teas/green" />);
const links = screen.getAllByRole("link");
expect(links.map((link) => link.textContent)).toEqual(["Home", "Shop", "Teas"]);
expect(links.map((link) => link.getAttribute("href"))).toEqual(["/", "/shop", "/shop/teas"]);
render(<Breadcrumbs path="/shop/teas/green" />);
expect(screen.queryByRole("link", { name: "Green" })).not.toBeInTheDocument();
expect(screen.getByText("Green")).toHaveAttribute("aria-current", "page");
render(<Breadcrumbs path="/shop/loose-leaf/EARL-GREY" />);
expect(screen.getByRole("link", { name: "Loose Leaf" })).toHaveAttribute("href", "/shop/loose-leaf");
expect(screen.getByText("Earl Grey")).toHaveAttribute("aria-current", "page");
render(<Breadcrumbs path="/shop//teas/" />);
const items = screen.getAllByRole("listitem");
expect(items.map((item) => item.textContent)).toEqual(["Home", "Shop", "Teas"]);
expect(screen.getByRole("link", { name: "Shop" })).toHaveAttribute("href", "/shop");
expect(screen.getByText("Teas")).toHaveAttribute("aria-current", "page");
render(<Breadcrumbs path="/" />);
expect(screen.getAllByRole("listitem")).toHaveLength(1);
expect(screen.queryByRole("link")).not.toBeInTheDocument();
expect(screen.getByText("Home")).toHaveAttribute("aria-current", "page");
const { rerender } = render(<Breadcrumbs path="/shop/teas/green" />);
rerender(<Breadcrumbs path="/about" />);
expect(screen.getAllByRole("listitem").map((item) => item.textContent)).toEqual(["Home", "About"]);
expect(screen.getByRole("link", { name: "Home" })).toHaveAttribute("href", "/");
expect(screen.getByText("About")).toHaveAttribute("aria-current", "page");
Run tests runs every test on your code, here in your browser. The problem is solved when they all pass.
Ctrl + Enter runs the tests (⌘ + Enter on a Mac).
I'm here to help with Breadcrumbs. I give hints, never the solution, so you get to solve it yourself. Ask for a hint, select code to ask about it, or press Ask Tuto why on a failing test.
Your first 3 answers need no account. for free to keep asking.