component 03 / 28WORKINGfeatured
SC Breadcrumb
- type
- Code Component
- platform
- Framer
- last update
- read time
- 5–6 min
- license
- SecretoCho Design
demo · runs with JavaScript
Builds an accessible breadcrumb trail from URL segments with configurable separators/alignment and emits JSON-LD (BreadcrumbList/optional BlogPosting) for SEO.
SC Breadcrumb builds a clean, responsive breadcrumb trail from the current URL, with configurable separator, max items (auto-ellipsis), alignment, and typography. It can also output schema.org JSON-LD for SEO (BreadcrumbList + optional BlogPosting), with empty-field cleanup for tidy markup.
- Navigation
- SEO
Main
Overview
- Built With
- React, CSS, Framer Code Component API
- Layout Support
- Fully Responsive (any width/height)
- Orientation
- Inline nav trail
- Ideal Use Case
- Page trails, article nav, SEO-friendly navigation
Tags
Code comment
/** * SC Breadcrumb * Dynamic breadcrumb trail + optional schema.org JSON-LD. * © SecretoCho Design – Aug 2025 * @framerDisableUnlink * @framerSupportedLayoutWidth any * @framerSupportedLayoutHeight any */Dependencies
- Technologies
- None (pure React + DOM)
- Notes
- No runtime libraries required; works with Framer’s standard runtime.
Complexity
- Logic Level
- Low–Medium (path parsing + schema build)
- Runtime Cost
- Very Low (simple text/links)
- Component Size
- ~2–3 KB (raw TSX)
- Notes
- JSON-LD injection is static; no reflow cost after render.
Guide
Instructions
- Drop SCBreadcrumb into your page header area.
- Set Separator (e.g., /, ›, →).
- Choose Max Items (older items collapse to …).
- Pick Alignment (Left/Center/Right).
- (Optional) Style with the Font, Color, Hover controls.
- (Optional) Enable SEO: fill Breadcrumb Name/Slug/Root and/or Blog fields to emit JSON-LD.
Examples / Presets
Classic
- separator
- "/"
- maxItems
- 3
- color
- #555
- hover
- #0A7
Chevrons
separator="›" · maxItems=4 · center
Minimal
separator="•" · maxItems=2 · right
Mechanics
How it Works
- Path parsing: window.location.pathname → /a/b/c → ['a','b','c'].
- Formatting: formatTitle() decodes URI, swaps -/_ with spaces, Title-Cases words.
- Overflow: If segments.length > maxItems, prepend … and keep the last maxItems segments.
- Link building: Each non-last crumb links to its cumulative absolute URL (origin + /a/...).
- Schema:
- BreadcrumbList uses Root → Name/Slug → (optional) Headline.
- BlogPosting uses blog fields (author/publisher/logo/image/dates).
- cleanObject() removes empty strings/arrays/objects before JSON-LD injection.
Performance & Tuning
- Text-only render; virtually zero layout cost.
- Avoid extremely long labels; rely on maxItems to keep trails short.
- Hover color changes are GPU-friendly; transition is limited to color.
Compatibility & Limits
- Requires window.location (client render). For SSR, outputs a safe fallback (/) until hydrated.
- JSON-LD is appended via <script type="application/ld+json">; safe in all evergreen browsers.
- Ellipsis crumb … is non-interactive by design.
Quality
Accessibility
- Use inside a <nav aria-label="Breadcrumb"> region when possible.
- Last item should not be a link; mark it as the current page (aria-current="page" if wrapped in an anchor).
- Separators are decorative—render as text with aria-hidden="true" or CSS ::before.
Security & Privacy
- No network calls or storage.
- JSON-LD strings are serialized, not executed; still ensure values come from trusted sources (avoid piping untrusted user input directly).
- Uses window.location only; no cookies or tracking.
- Small surface area; no global listeners.
Reference
Props
| name | type | default | description |
|---|---|---|---|
font | Font | {"Inter",400,"1rem"} | Typography for items |
color | string | #555 | Link/label color |
hoverColor | string | #009658 | Hover color |
separator | string | / | Character between crumbs (e.g., / › →) |
maxItems | number | 3 | Max visible segments (older collapse to …) |
gap | number | 8 | Space between crumbs (px) |
alignment | enum | flex-start | Flex alignment (flex-start|center|flex-end) |
sectionId | string | breadcrumb-section | Wrapper id attribute |
schemaName | string | "" | Breadcrumb display name (e.g., “Blog”) |
schemaSlug | string | "" | Breadcrumb slug (e.g., "blog") |
schemaRoot | string | Home | Root label for position 1 |
blogHeadline | string | "" | Article headline |
blogDescription | string | "" | Short description |
blogImage | image | "" | Primary image URL |
blogImageHeight | number | 800 | Image height (px) |
blogImageWidth | number | 1200 | Image width (px) |
blogAuthorName | string | "" | Author full name |
blogAuthorURL | string | "" | Author profile/home URL |
blogPublisherName | string | "" | Publisher name |
blogPublisherLogo | image | "" | Publisher logo URL |
blogPublisherLogoHeight | number | 60 | Logo height (px) |
blogPublisherLogoWidth | number | 600 | Logo width (px) |
blogPublishDate | string | "" | ISO date published (YYYY-MM-DD) |
blogModifiedDate | string | "" | ISO date modified (YYYY-MM-DD) |
Notes & Tips
- Overflow UX: The … represents skipped ancestors; keep maxItems 2–4 for clarity.
- Chevrons: For a chevron look, set separator="›" and tighten gap=6.
- Centering: For centered trails within fluid layouts, ensure the parent has display:block with adequate width.
- Framer control quirk: Alignment value should be flex-start/center/flex-end (the UI shows “Left/Center/Right”).
Troubleshooting / FAQ
My alignment doesn’t change.
Use flex-start|center|flex-end; if imported presets use "left", switch to flex-start.
Labels look odd (“My%20Post”).
The component decodes URI; if still wrong, confirm your route slugs.
Home links to a relative path.
Origin comes from window.location.origin; verify your domain/protocol in previews.
JSON-LD not visible.
It won’t render UI—check page source (client) or DevTools Elements for <script type="application/ld+json">.
Source
Header comment
/** * SC Dynamic Breadcrumb * --------------------- * - URL-based breadcrumb with overflow handling * - SPA navigation (single boolean control) * - BreadcrumbList + BlogPosting JSON-LD (optional) * - Canvas-safe preview path */Key excerpt
The trail from the URL: segments past the limit fold into “…”, each crumb links to its own path prefix, and a BreadcrumbList is built for JSON-LD.
// -------- Build items -------- const segments = pathForBuild.split("/").filter(Boolean) const effectiveMax = Math.max(1, Math.min(layoutMax, 50)) const hasOverflow = segments.length > effectiveMax const visibleSegs = hasOverflow ? segments.slice(-effectiveMax) : segments const all = ["home", ...(hasOverflow ? ["..."] : []), ...visibleSegs] const buildHref = (idx: number): string | null => { const isLast = idx === all.length - 1 const seg = all[idx] if (seg === "..." || isLast) return null if (seg === "home") return origin const ahead = all.length - idx - 1 const segCount = segments.length - ahead return `${origin}/${segments.slice(0, segCount).join("/")}` } const items = all.map((seg, i) => ({ key: i, segment: seg, label: seg === "home" ? "Home" : seg === "..." ? "…" : formatSegment(seg), href: buildHref(i), isLast: i === all.length - 1, })) // -------- Schema -------- const breadcrumbSchema = breadcrumbEnabled ? cleanObject({ "@context": "https://schema.org", "@type": "BreadcrumbList", itemListElement: [ { "@type": "ListItem", position: 1, name: breadcrumbRootName, item: origin, }, breadcrumbCategoryName && { "@type": "ListItem", position: 2, name: breadcrumbCategoryName, item: `${origin}/${breadcrumbCategorySlug}`, }, blogHeadline && { "@type": "ListItem", position: 3, name: blogHeadline, }, ].filter(Boolean), }) : nullCredits
Credits
Designed and implemented by SecretoCho Design. Pattern-safe URL formatting and schema cleanup helpers included.
- license
- SecretoCho Design
SecretoCho Design 2025
Disclaimer
Provided “as is” for navigation/SEO convenience. Validate structured data in your environment (Search Console/Rich Results Test) and ensure all values (images, author, publisher) are licensed and accurate.
Proves
Hiring a design engineer?
I’m open to senior design engineer roles: remote from Belgrade, or relocation with visa sponsorship. Write to me, or read the CV first. Client work stays selective, one project at a time.
sc@secretocho.design