Skip to content

viewer: resolve bundle-relative markdown links in concept bodies - #362

Open
aadehamid wants to merge 2 commits into
GoogleCloudPlatform:mainfrom
aadehamid:viz-relative-links
Open

viewer: resolve bundle-relative markdown links in concept bodies#362
aadehamid wants to merge 2 commits into
GoogleCloudPlatform:mainfrom
aadehamid:viz-relative-links

Conversation

@aadehamid

@aadehamid aadehamid commented Aug 29, 2026

Copy link
Copy Markdown

Problem

The detail panel's rewriteInternalLinks only rewires hrefs in OKF's recommended absolute form (/tables/customers.md). Bundles that use the relative form explicitly allowed by SPEC §6.1 (e.g. ../entities/foo.md) fall through to the external-link path. Following such a link in a browser produces ERR_FILE_NOT_FOUND instead of navigating within the graph.

Relative links are common in practice for bundles consumed by more than one tool — e.g. a bundle also read as an Obsidian vault, where relative links (with URL-encoded spaces, ../entities/My%20Concept.md) are the form Obsidian itself generates and resolve natively.

Note the inconsistency this creates within the viewer itself: the Python side already handles relative hrefs correctly — _extract_links resolves them against the document directory when building graph edges — so the graph edges exist and render, but the same links are dead in the detail panel.

Fix

  • rewriteInternalLinks now receives the current concept id and resolves relative .md hrefs against its directory. A new resolveRelative helper handles ./.. segments and decodes URL-encoded characters such as %20.
  • A relative target that resolves to an existing concept now navigates within the graph, identical to absolute-form behavior.
  • Unresolvable targets and non-.md/scheme/anchor hrefs keep the existing external-link behavior.

Testing

  • node --check passes on the patched file.
  • Verified against a real 3-bundle corpus (574 concepts, ~1,900 edges) whose links are all relative-form: before the patch, every in-document link errored with ERR_FILE_NOT_FOUND; after, a sampled 178/178 relative hrefs resolve to concept ids and navigate correctly.
  • Graph edges (built by _extract_links) were unchanged before/after the patch, confirming the body-link path now agrees with the edge path.

The viewer's rewriteInternalLinks only rewired hrefs in OKF's
recommended absolute form ('/tables/customers.md'). Bundles that use
the relative form explicitly allowed by SPEC 6.1 (e.g.
'../entities/foo.md' — common when bundles are also read in tools
like Obsidian) fell through to the external-link path, and following
them in a browser produced ERR_FILE_NOT_FOUND instead of navigating.

Pass the current concept id into rewriteInternalLinks and resolve
relative hrefs against its directory (handling '.' and '..' segments
and URL-encoded characters such as %20). A relative target that
resolves to an existing concept now navigates within the graph,
matching the absolute-form behavior; targets that do not resolve
still open externally.
@google-cla

google-cla Bot commented Aug 29, 2026

Copy link
Copy Markdown

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

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.

1 participant