Barrierefreie Breadcrumbs mit Claude Code
Breadcrumbs mit Claude Code, JSON-LD, aria-current, mobilem CSS und Tests für React/Astro umsetzen.
Breadcrumbs wirken wie eine kleine Zeile über der Überschrift. In produktiven Websites verbinden sie aber Informationsarchitektur, interne Links, Barrierefreiheit, strukturierte Daten und mobile Darstellung. Eine schwache Umsetzung kann optisch funktionieren, während Screenreader die aktuelle Seite nicht erkennen, JSON-LD relative URLs enthält oder lange Titel auf dem Smartphone den Einstieg verdrängen.
In ClaudeCodeLab-Templates erzeugte Claude Code nach einem knappen Prompt zunächst Home > Blog > Title. Es fehlten jedoch aria-current, absolute URLs im JSON-LD, sauberes Mobile-Verhalten und menschenlesbare Labels für dynamische Slugs. Der Unterschied liegt im Prompt: Claude Code braucht den vollständigen Vertrag.
Dieser Leitfaden zeigt die Umsetzung für React, Next.js-ähnliche Sites und Astro. Passende Grundlagen sind SEO-Optimierung, Barrierefreiheit, Astro und React.
Designvertrag
Breadcrumbs ersetzen nicht den Zurück-Button. Sie zeigen Hierarchie, führen zu übergeordneten Seiten und erklären Suchmaschinen die Beziehung zwischen Seiten. Das WAI-ARIA APG Breadcrumb Pattern beschreibt eine beschriftete Navigationsregion und aria-current="page" für die aktuelle Seite.
Strukturierte Daten folgen schema.org BreadcrumbList. Jedes Element braucht eine position, damit die Reihenfolge eindeutig ist. Für Google Search ist die offizielle Dokumentation zu Breadcrumb structured data die passende Primärquelle.
| Entscheidung | Festlegen | Häufiger Fehler |
|---|---|---|
| Labels | Titel, Kategorien oder Wörterbuch | Roh-Slugs werden angezeigt |
| URLs | HTML-Links und absolute JSON-LD-URLs | Relative Pfade in strukturierten Daten |
| Aktuelle Seite | Link oder Text im letzten Item | Status nur über Farbe |
| Mobile | Vollständig oder mittig gekürzt | Mehrzeilige Breadcrumb-Leiste |
| Sprachen | Prefix und lokalisierte Labels | Sprachmix in Navigation/JSON-LD |
Prompt für Claude Code
Implementiere Breadcrumbs für eine React/Next.js- oder Astro-Site.
Anforderungen:
- items als { label: string; href: string }[] akzeptieren.
- Dem letzten Item aria-current="page" geben.
- nav aria-label="Breadcrumb" verwenden.
- Trenner mit aria-hidden="true" markieren.
- JSON-LD BreadcrumbList aus demselben items-Array erzeugen.
- JSON-LD-URLs mit siteUrl in absolute URLs umwandeln.
- Helper für items aus pathname hinzufügen.
- Slugs lesbar formatieren und Label-Wörterbuch erlauben.
- Auf Mobile mittlere Items ausblenden, aktuelle Seite lesbar halten.
- Vitest für Root, tiefe Pfade, lokalisierte Labels und Query Strings ergänzen.
- Danach Accessibility- und Structured-Data-Checks auflisten.
Für größere Änderungen lohnt eine zweite Prüfung mit der Claude Code Review-Checkliste.
React-Komponente
import type { ReactNode } from "react";
export type BreadcrumbItem = {
label: string;
href: string;
};
type BreadcrumbProps = {
items: BreadcrumbItem[];
siteUrl: string;
ariaLabel?: string;
};
function toAbsoluteUrl(siteUrl: string, href: string) {
return new URL(href, siteUrl).toString();
}
function Separator(): ReactNode {
return (
<span className="breadcrumb__separator" aria-hidden="true">
/
</span>
);
}
export function Breadcrumb({
items,
siteUrl,
ariaLabel = "Breadcrumb",
}: BreadcrumbProps) {
if (items.length <= 1) return null;
const jsonLd = {
"@context": "https://schema.org",
"@type": "BreadcrumbList",
itemListElement: items.map((item, index) => ({
"@type": "ListItem",
position: index + 1,
item: {
"@id": toAbsoluteUrl(siteUrl, item.href),
name: item.label,
},
})),
};
return (
<>
<nav className="breadcrumb" aria-label={ariaLabel}>
<ol className="breadcrumb__list">
{items.map((item, index) => {
const isCurrent = index === items.length - 1;
return (
<li className="breadcrumb__item" key={item.href}>
{index > 0 ? <Separator /> : null}
{isCurrent ? (
<span className="breadcrumb__current" aria-current="page">
{item.label}
</span>
) : (
<a className="breadcrumb__link" href={item.href}>
{item.label}
</a>
)}
</li>
);
})}
</ol>
</nav>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
/>
</>
);
}
Routen-Helper
import type { BreadcrumbItem } from "@/components/Breadcrumb";
export type BreadcrumbLabels = Record<string, string>;
function titleize(segment: string) {
return decodeURIComponent(segment)
.replace(/[-_]+/g, " ")
.replace(/\b\w/g, (char) => char.toUpperCase());
}
export function buildBreadcrumbs(
pathname: string,
labels: BreadcrumbLabels = {},
): BreadcrumbItem[] {
const cleanPath = pathname.split(/[?#]/)[0].replace(/\/+$/, "") || "/";
const segments = cleanPath.split("/").filter(Boolean);
const items: BreadcrumbItem[] = [
{ label: labels["/"] ?? "Home", href: "/" },
];
let href = "";
for (const segment of segments) {
href += `/${segment}`;
items.push({
label: labels[href] ?? labels[segment] ?? titleize(segment),
href,
});
}
return items;
}
import { Breadcrumb } from "@/components/Breadcrumb";
import { buildBreadcrumbs } from "@/lib/breadcrumbs";
const siteUrl = "https://claudecodelab.com";
export default async function ArticlePage() {
const pathname = "/de/blog/claude-code-breadcrumb-navigation";
const labels = {
"/": "Start",
"/de": "Deutsch",
"/de/blog": "Artikel",
"/de/blog/claude-code-breadcrumb-navigation":
"Barrierefreie Breadcrumbs mit Claude Code",
};
const items = buildBreadcrumbs(pathname, labels);
return (
<main>
<Breadcrumb items={items} siteUrl={siteUrl} ariaLabel="Breadcrumb" />
<h1>Barrierefreie Breadcrumbs mit Claude Code</h1>
</main>
);
}
Für Astro bleibt die Datenform gleich; nutze Astro.url.pathname und gib JSON-LD mit set:html={JSON.stringify(jsonLd)} aus.
CSS, Tests und Prüfung
.breadcrumb { margin-block: 0 1rem; font-size: 0.875rem; color: #4b5563; }
.breadcrumb__list { display: flex; flex-wrap: wrap; gap: 0.25rem; list-style: none; margin: 0; padding: 0; }
.breadcrumb__item { align-items: center; display: inline-flex; min-width: 0; }
.breadcrumb__link { color: #2563eb; text-decoration: underline; text-underline-offset: 0.15em; }
.breadcrumb__current { color: #111827; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.breadcrumb__separator { color: #9ca3af; margin-inline: 0.35rem; }
@media (max-width: 640px) {
.breadcrumb__list { flex-wrap: nowrap; }
.breadcrumb__item:not(:first-child):not(:nth-last-child(-n + 2)) { display: none; }
.breadcrumb__item:nth-last-child(2)::after { color: #9ca3af; content: "..."; margin-inline: 0.35rem; }
.breadcrumb__current { max-width: 58vw; }
}
import { describe, expect, it } from "vitest";
import { buildBreadcrumbs } from "./breadcrumbs";
describe("buildBreadcrumbs", () => {
it("returns only Home for the root path", () => {
expect(buildBreadcrumbs("/")).toEqual([{ label: "Home", href: "/" }]);
});
it("builds nested breadcrumbs and ignores query strings", () => {
expect(buildBreadcrumbs("/blog/claude-code?page=2")).toEqual([
{ label: "Home", href: "/" },
{ label: "Blog", href: "/blog" },
{ label: "Claude Code", href: "/blog/claude-code" },
]);
});
it("uses localized labels when provided", () => {
expect(
buildBreadcrumbs("/de/blog/claude-code-breadcrumb-navigation", {
"/": "Start",
"/de": "Deutsch",
"/de/blog": "Artikel",
"/de/blog/claude-code-breadcrumb-navigation": "Breadcrumbs",
}),
).toEqual([
{ label: "Start", href: "/" },
{ label: "Deutsch", href: "/de" },
{ label: "Artikel", href: "/de/blog" },
{ label: "Breadcrumbs", href: "/de/blog/claude-code-breadcrumb-navigation" },
]);
});
});
E2E prüft nav[aria-label], genau ein aria-current="page", parsebares JSON-LD, absolute URLs und Mobile-Layout. Siehe auch Playwright-Tests.
Anwendungsfälle, Risiken und CTA
Wichtige Anwendungsfälle sind Blogs/Dokumentationen, Ecommerce- und Trainingsseiten, tiefe SaaS-Einstellungen und mehrsprachige Sites. Typische Fehler sind Farb-only-Status, relative JSON-LD-URLs, rohe Slugs, kaputtes Mobile-Layout und getrennte Datenquellen für UI und JSON-LD.
Vor Veröffentlichung: aria-label, aria-current, versteckte Trenner, BreadcrumbList, position, absolute URLs, Konsistenz zwischen UI und JSON-LD, Mobile, Sprache und Search Console prüfen.
Auf ClaudeCodeLab stützen Breadcrumbs den Weg von Artikeln zur kostenlosen Checkliste, zu Produkten und zu Claude Code Training/Consulting. Ich habe die Beispiele als React-Komponente, Helper und Vitest-Test geprüft; entscheidend war eine gemeinsame items-Quelle für UI und JSON-LD.
Fazit
Gute Breadcrumbs sind keine Dekoration. Gib Claude Code Labels, Routen, aria-current, JSON-LD, absolute URLs, Mobile-Verhalten und Tests vor und reviewe das Ergebnis anhand der offiziellen Quellen.
Kostenloses PDF: Claude-Code-Cheatsheet
E-Mail eintragen und eine Seite mit Befehlen, Review-Gewohnheiten und sicheren Workflows herunterladen.
Wir schützen Ihre Daten und senden keinen Spam.
Über den Autor
Masa
Engineer für praktische Claude-Code-Workflows und Team-Einführung.
Ähnliche Artikel
Claude Code Permission Safety Ladder: Zugriff kontrolliert erweitern
Von read-only zu begrenzten Änderungen, Prüfbefehlen und Deploy-Checks mit klarer Kontrolle.
Claude Code Small PR Proof Pack: kleine Änderungen reviewbar machen
Ein Proof Pack für Claude-Code-PRs: Diff, Checks, öffentliche URL, CTA-Pfad und Rollback.
Claude-Code-Review-Gate vor dem Commit
Vor dem Commit mit Claude Code prüfen: Diff, Build, öffentliche URL, Gumroad-Links, Beratung-CTA, fehlende Tests und fremde Dateien.