Skip to content

fix(router): standardize link and resource path resolution - #2793

Open
sy-records wants to merge 2 commits into
developfrom
feat/path
Open

fix(router): standardize link and resource path resolution#2793
sy-records wants to merge 2 commits into
developfrom
feat/path

Conversation

@sy-records

Copy link
Copy Markdown
Member

Summary

Standardize path handling for links, images, and embedded resources.

This change:

  • Resolves relative paths from the Markdown page where they are declared by default.
  • Resolves absolute paths from the domain root.
  • Adds relativeBasePath and absoluteBasePath configuration options.
  • Adds a per-element :basepath Markdown attribute.
  • Safely falls back to standard path handling when a base path is invalid.
  • Prevents configured local base paths from being duplicated.
  • Preserves SPA routing for external basePath sources.
  • Keeps sidebar links and generated subheadings active when using domain-root hash routes.
  • Updates documentation and adds unit, integration, and browser regression tests.

No UI changes are introduced, so before/after screenshots are not applicable.

Related issue, if any:

Fixes #1891

What kind of change does this PR introduce?

  • Bugfix
  • Feature
  • Code style update (formatting, renaming)
  • Refactoring (no functional changes, no api changes)
  • Build related changes
  • Documentation content changes
  • Other (please describe):

For any code change,

  • Related documentation has been updated, if needed
  • Related tests have been added or updated, if needed

Does this PR introduce a breaking change?

  • Yes
  • No

Relative links are now resolved from the current Markdown page by default because relativePath defaults to true. Applications that depend on the previous index-relative behavior can restore it with:

window.$docsify = {
  relativePath: false,
};

Absolute paths now resolve from the domain root. Sites that want absolute paths rooted at the Docsify site directory can configure absoluteBasePath.

The default basePath value is now null instead of an empty string.

Tested in the following browsers:

  • Chrome
  • Firefox
  • Safari
  • Edge

- resolve relative paths from the current Markdown page
- resolve absolute paths from the domain root
- add configurable and per-element base path overrides
- prevent duplicate base paths and preserve sidebar activation
- add regression tests and configuration documentation

Fixes #1891
@vercel

vercel Bot commented Aug 25, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
docsify-preview Ready Ready Preview Aug 28, 2026 4:52pm


expect(output).toMatchInlineSnapshot(
'"<p><a href="#/url" target="_blank">alt text</a></p>"',
'"<p><a href="/#/url" target="_blank">alt text</a></p>"',

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is this ok without the leading hash symbol?

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Yes, /#/url is correct. The hash symbol is present — it's the / (domain root) followed by #/url (the hash route). In hash routing, links resolve to /<base>#/<path>, so the leading / comes first. This matches the output of HashHistory.toURL which returns '#' + super.toURL(...) prepended to the site root path.

import { History } from '../../src/core/router/history/base.js';

class MockHistory extends History {
mode = 'hash';

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Are we testing both modes? Need to test both. @copilot make sure the same tests run in both modes.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Done. Refactored the file to use a runBaseHistoryTests(label, HistoryClass) helper that defines all the suites once and runs them for both MockHistory (hash mode) and MockHTML5History (history mode). All 24 tests pass (12 per mode). Both modes test relativePath: true, relativePath: false, default path behavior, and getFile.

@trusktr

trusktr commented Aug 28, 2026

Copy link
Copy Markdown
Member

Getting ready for 6.0 I see!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: Docsify's path handling is problematic (and broken in some scenarios)

3 participants