Bug: Docsify's path handling is problematic (and broken in some scenarios)
- Dominant language
- JavaScript
- Stars
- 31.5k
- Forks
- 5.8k
- Avg merge
- 9d 8h
- Merged PRs (30d)
- 2
Description
# Bug Report
Docsify's default path handling is problematic and/or broken in several scenarios:
1. **Docsify's path behavior is inconsistent**
Docsify handles paths differently for links and other resources like images and embedded content. This inconsistency requires users to research and memorize how and why path behavior varies based on resource type which is unnecessarily confusing and makes Docsify unintuitive for users.
2. **Docsify's relative path behavior is non-standard**
Relative paths are generally expected to be relative to the context in which they are used. In the context of a website made up of a collection of separate pages, this means relative paths should be relative to the page where they are used. This provides document portability by allowing links between documents and resources to remain intact as they are moved throughout the hierarchy so long as their location relative to each other remains the same.
- 🟢 Docsify treats relative _non-link_ paths (images, embedded content, ...) as relative to the current page route. This is the correct behavior for relative paths.
- 🟡 Docsify treats relative _link_ paths as relative to a site's `index.html` route. This makes sense from a technical perspective, but this is not expected behavior based on how relative paths work elsewhere. For sites with a flat hierarchy where the `index.html` and markdown pages are located at the root (`/`) this isn't an issue, but for sites with nested routes (e.g., `/dir/page.md`) or a nested `index.html` (e.g., `/docs/index.html`) this results in confusion, the need to use unintuitive paths, and broken or incorrect links.
3. **Docsify's absolute path behavior is non-standard**
Absolute paths are generally expected to be relative to the top-most level in a domain or directory hierarchy. In the context of a Docsify site, this most commonly means the root of the domain (`/`), but nested sites (`/docs/index.html`) may prefer to have absolute paths relative to the `index.html` route for site portability. This provides consistent and reliable paths to resources from any level within the hierarchy (e.g., accessing `/assets/image.png` from `/`, `/foo/`, or `/foo/bar/baz`).
- 🟡 Docsify treats absolute _non-link_ paths (images, embedded content, ...) as relative to the current page route. This is not how absolute paths work elsewhere which causes confusion, the need to use unintuitive paths, and broken or incorrect links.
- 🟡 Docsify treats relative _link_ paths as relative to a site's `index.html` route. This is not how absolute paths work elsewhere which causes confusion, the need to use unintuitive paths, and broken or incorrect links.
- 🔴 Docsify's handling of absolute paths prevents absolute paths from being used to access resources above the site's level in the hierarchy. For example, it is not possible to access `/assets/image.png` from `/dir/page.md` using an absolute URL.
4. **Docsify's absolute path behavior is broken for nested routes**
🔴 In Docsify attempt to treat absolute _non-link_ paths (images, embedded content, ...) as relative to the current page route, it incorrectly adds the current page route to paths that already contain the page route. For example:
```
[Root]
└─ docs
├─ dir
│ ├─ image.png
│ └─ page.md
├─ index.html
└─ README.md
```
```markdown

```
Result:
```html
```
5. **Docsify does not provide a way to modify or opt-out of its problematic handling of absolute paths**
This has led users resorting to using HTML instead of markdown and PRs like #1868 which propose working around these issues by introducing more options or custom markdown syntax. None of these would be necessary if paths simply worked the way people expected them to by default. Docsify does offer configuration options like `basePath` and `relativePath`, but neither of these issues allows paths in Docsify to work the way they do outside of Docsify and as people expect them to.
The result has been many issues and PRs that remain unresolved. These are the ones I've found from a very simple search for "absolute" and "relative". There are most likely others that are not accounted for here.
- #2370
- #2369
- #1982
- #1763
- #1761
- #1684
- #1631
- #1569
- #1407
- #1033
- #850
- #877
- #424
- #415
- #2570
## Steps to reproduce
To help others understand the problem, I have created a demo link and non-link paths can be tested:
[](https://codesandbox.io/s/docsify-1868-uyzmvg?file=/README.md)
## What is current behaviour
Test results from the [Codesandbox Demo](https://codesandbox.io/s/docsify-1868-uyzmvg?file=/README.md) can be seen in the following table:

## What is the expected behaviour
1. Paths should be consistent for all resource types.
2. All relative paths should be relative to the page in which they are used by default.
3. All absolute paths should be relative to the top-most level in the domain or directory hierarchy by default.
4. Configuration options should allow users to define base paths for relative and absolute links:
- `basePath`: Defaults to `null`. Functionally the same as setting `relativeBasePath` and `absoluteBasePath` to the same value.
- `relativeBasePath`: Defaults to current page route. Overrides `basePath`.
- `absoluteBasePath`: Defaults to `/`. Overrides `basePath`.
5. A `:basepath` markdown attribute (or similar) should allows specifying the base path for individual elements. This is required to allow accessing resources outside of the current `index.html` route when one of the base path options above would otherwise prevent it. For example:
```
[Root]
├─ assets
│ └─ image.png
└─ docs
├─ index.html
└─ README.md
```
```js
window.docsify = {
basePath: '/docs/`
}
```
```markdown


```
Result:
```html
```
If these changes are implemented, the default behavior will be as follows:
Contributor guide
Assessment
This issue has not been assessed yet.