Skip to content

Match breadcrumb parents on same host and whole path segments - #373

Open
pxul wants to merge 2 commits into
kepano:mainfrom
pxul:fix-breadcrumb-path-matching
Open

Match breadcrumb parents on same host and whole path segments#373
pxul wants to merge 2 commits into
kepano:mainfrom
pxul:fix-breadcrumb-path-matching

Conversation

@pxul

@pxul pxul commented Aug 26, 2026

Copy link
Copy Markdown

Fixes #372

The "section breadcrumb" rule in removeByContentPattern decides whether a link points at a parent section of the current page by testing urlPath.startsWith(linkPath).

That check has two faults. It compares pathnames and never the host, so a link to another site is eligible. It also lets the match stop part-way through a segment, so /acme counts as a parent of /acmelabs/posts/12345. Either fault deletes a link along with its text, and nothing in the output indicates the removal.

The changes here are in two commits, one per missing guard, so either can be dropped.

1. Compare the host

A link to any site was eligible for deletion, because linkPath is only a pathname. A page at https://pages.example.com/acmelabs/posts/12345 would delete a link to https://social.example.net/acme.

pageHost was already computed and went unused until the trailing external-link rule further down, so the new guard reuses it.

The rule's block comment listed the matching patterns without ever saying the link must be same-site, so a line has been added for that.

2. Require a whole-segment match

startsWith can match partial segments, so /acme was treated as a parent of /acmelabs/posts/12345.

The page path is now tested against the link path with a trailing /, so a match has to end on a segment boundary: /acmelabs/posts/12345 starts with /acmelabs/, but not with /acme/. A link path already ending in / is used as it stands, so the slash is never doubled.

Pattern 1 in the block comment now says "whole-segment path prefix". The counter-example sits in the inline comment beside the check rather than being repeated in the block.

Behaviour

page link before after
/acmelabs/posts/12345 /acmelabs removed removed
/acmelabs/posts/12345 /acmelabs/ removed removed
/acmelabs/posts/12345 /acmelabs/posts removed removed
/acmelabs/posts/12345 /acmelabs/posts/ removed removed
/acmelabs/posts/12345 /acme removed kept
/acmelabs/posts/12345 /ac removed kept
/acmelabs/posts/12345 https://social.example.net/acme removed kept

Tests

tests/breadcrumb-removal.test.ts, three cases reporting as six tests:

  • a link to another host whose path prefixes the page path is kept (commit 1)
  • a same-site link whose path prefixes the page path mid-segment is kept (commit 2)
  • links to real parent paths are still removed — parameterised over four hrefs: one and two segments up, each with and without a trailing slash

The third case guards the other two: a boundary check tightened too far would keep every link, and only this case would notice. It also checks the surrounding article is still there, because all its assertions are about links being gone, and those would pass even if extraction returned nothing at all.

The first two cases were each confirmed failing before their fix. The third passes on both sides by design, since it asserts behaviour the rule already had.

The full suite passes, including the two fixtures that cover what this rule is meant to do: content-patterns--leading-breadcrumb.html and general--back-nav-link.html. Both link within the site (/archive, ../index.html), so neither is affected.

Not included

Trailing-slash equivalence. The linkPath !== urlPath guard exempts a link to the page itself, but only on an exact string match, so a page at /blog/ still loses a link to /blog. Whether /a and /a/ should count as one resource reads as a policy question rather than a bug, and it may bear on other rules, so it is left alone here.

A helper for /^www\./. The new host guard strips www. inline, matching the two existing uses in this file and four more across src/metadata.ts and two extractors. A shared utility would spread this diff over files that have nothing to do with breadcrumbs, so the existing style is followed instead.

Happy to follow up on either if you would like.

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.

Some links are incorrectly removed when their target path partially matches the page's path

1 participant