Skip to content

Conversation

@ameshkin
Copy link
Owner

@ameshkin ameshkin commented Nov 26, 2025

Note

Adds JSON-LD utilities, strengthens router breadcrumb hooks/components, introduces subpath ESM exports, and expands docs/tests with Playwright/Cucumber.

  • Core & Exports
    • Add NextCrumb alias; keep Breadcrumbs as primary export.
    • Introduce subpath ESM exports: breadcrumbs, hooks/usePathBreadcrumbs, hooks/useReactRouterBreadcrumbs, utils/jsonld.
    • Update tsup to build multiple entrypoints; tweak externals.
  • Hooks
    • usePathBreadcrumbs: add rootLabel, safer decoding/formatting, exclusion set optimization, edge-case handling.
    • useReactRouterBreadcrumbs: lazy-load react-router-dom, add basePath, robust decode/exclude/mapping, defaults when router absent.
  • Component
    • Breadcrumbs.tsx: safer item handling, stable keys, customizable ARIA/spacing/styles; home icon logic and external-link attrs.
  • SEO Utilities
    • New utils/jsonld: toJsonLd, BreadcrumbJsonLd, breadcrumbsToJsonLd with safety checks and origin handling.
  • Docs
    • Major README updates (optional react-router-dom, Next/React Router guides, JSON-LD usage).
    • New docs: docs/next-router.md, docs/react-router.md, docs/vanilla-json.md, docs/gitlab.md, docs/changes.md.
  • Testing & Tooling
    • Add extensive unit/edge tests for components/hooks/utils.
    • Add Playwright UI tests and Cucumber BDD tests; include playwright.config.ts.
  • Package
    • Bump version to 0.1.5; add workspaces; update dev deps; refine peer deps (optional react-router-dom).

Written by Cursor Bugbot for commit 8ad3d2e. This will update automatically on new commits. Configure here.

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the final PR Bugbot will review for you during this billing cycle

Your free Bugbot reviews will reset on December 17

Details

You are on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle.

To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.

Bug: Hook fails in ESM-only environments

The dynamic module loading logic only works in CommonJS environments where require is defined. In pure ESM environments (browsers, Vite, or when the package is consumed as ESM), require is undefined, causing routerModule to remain null and the function to always throw an error - even when react-router-dom is installed. Since the package exports only ESM format ("type": "module"), this hook is fundamentally broken for all consumers. There's no code path that actually loads the module in ESM environments, despite the comment claiming to rely on it being available.

src/hooks/useReactRouterBreadcrumbs.ts#L59-L73

// Try CommonJS require (for Node.js/CommonJS environments)
if (typeof require !== 'undefined') {
try {
routerModule = require(mod)
} catch {
// require failed, module not available
}
}
// For ESM environments, the module should be available through
// normal module resolution if installed. Since we can't use
// dynamic import() synchronously, we rely on the consuming
// project to have it available or configure webpack appropriately.
if (!routerModule) {
throw new Error("react-router-dom not available")

Fix in Cursor Fix in Web


if (!rootLabel && items.length === 0) items.push({ label: "Home", href: "/" })
return items
}, [pathname, rootLabel, basePath, decode, JSON.stringify(exclude), mapSegmentLabel])
}, [pathname, rootLabel, basePath, decode, exclude, mapSegmentLabel])
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Array dependency causes unnecessary re-renders

The useMemo dependency array includes the raw exclude array, which causes the memoization to break on every render since arrays are compared by reference. When a parent component re-renders and passes a new array instance (even with identical values), this hook will unnecessarily recompute. The usePathBreadcrumbs hook correctly handles this by converting the array to a Set in a separate useMemo and using that as a dependency, but this pattern wasn't applied here.

Fix in Cursor Fix in Web


return items;
}, [parts, baseHref, labelMap, decode, transformLabel]);
}, [parts, baseHref, labelMap, decode, transformLabel, rootLabel]);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Object dependency causes unnecessary re-renders

The useMemo dependency array includes the raw labelMap object, which causes the memoization to break on every render since objects are compared by reference. When a parent component re-renders and passes a new object instance (even with identical key-value pairs), this hook will unnecessarily recompute. This is the same pattern issue as with the exclude array - objects and arrays need special handling to avoid reference comparison breaking memoization.

Fix in Cursor Fix in Web

@ameshkin ameshkin merged commit d475ada into main Nov 26, 2025
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants