diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml
index 5326336cc6..0c8ea6d125 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.yml
+++ b/.github/ISSUE_TEMPLATE/bug_report.yml
@@ -33,7 +33,7 @@ body:
label: Steps to reproduce
description: |
A description with steps to reproduce the issue.
- Provide a link to a public repository or create a reproducible [sandbox](https://codesandbox.io/s/307qqv236):
+ Provide a link to a public repository or create a reproducible [sandbox](https://sandbox.docsifyjs.org/):
placeholder: |
1. Step 1
2. Step 2
diff --git a/.github/semantic.yml b/.github/semantic.yml
deleted file mode 100644
index e7f5bb59b9..0000000000
--- a/.github/semantic.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-titleAndCommits: true
-allowMergeCommits: true
-allowRevertCommits: true
-anyCommit: true
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 8bb0b5348b..8019d5ce43 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -96,7 +96,7 @@ jobs:
uses: actions/upload-artifact@v7
if: failure()
with:
- name: ${{ matrix.os }}-${{ matrix.node-version }}-artifacts
+ name: test-artifacts-${{ github.run_id }}-${{ github.run_attempt }}
path: |
_playwright-results/
_playwright-report/
diff --git a/README.md b/README.md
index 192a8c00f4..5813199be6 100644
--- a/README.md
+++ b/README.md
@@ -41,7 +41,7 @@ Docsify turns one or more Markdown files into a Website, with no build process r
Get going fast by using a static web server or GitHub Pages with this ready-to-use [Docsify Template](https://github.com/docsifyjs/docsify-template), review the [quick start tutorial](https://docsify.js.org/#/quickstart) or jump right into a CodeSandbox example site with the button below.
-[](https://codesandbox.io/s/307qqv236)
+[](https://sandbox.docsifyjs.org/)
## Showcase
diff --git a/docs/README.md b/docs/README.md
index 48fb465889..b3aefaa74e 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -17,7 +17,7 @@ Docsify turns your Markdown files into a documentation website instantly. Unlike
## Examples
-Check out the [Showcase](https://github.com/docsifyjs/awesome-docsify#showcase) to see docsify in use.
+Check out the [Showcase](awesome?id=showcase) to see docsify in use.
## Donate
diff --git a/docs/configuration.md b/docs/configuration.md
index 7b61752984..23ca300b93 100644
--- a/docs/configuration.md
+++ b/docs/configuration.md
@@ -306,6 +306,20 @@ window.$docsify = {
};
```
+## sidebarPosition
+
+- Type: `String`
+- Default: `'left'`
+
+Controls which side of the page displays the sidebar. Set this to `'right'` to
+place the sidebar and its toggle on the right.
+
+```js
+window.$docsify = {
+ sidebarPosition: 'right',
+};
+```
+
## homepage
- Type: `String`
diff --git a/docs/plugins.md b/docs/plugins.md
index 00da722c81..bca83191b4 100644
--- a/docs/plugins.md
+++ b/docs/plugins.md
@@ -65,6 +65,11 @@ By default, the hyperlink on the current page is recognized and the content is s
// You can provide a regexp to match prefixes. In this case,
// the matching substring will be used to identify the index
pathNamespaces: /^(\/(zh-cn|ru-ru))?(\/(v1|v2))?/,
+
+ // Show where each result comes from (default: 'none')
+ // 'page': the page title, e.g. "Guide"
+ // 'breadcrumb': the sidebar path, e.g. "Basics โบ Guide"
+ resultSource: 'none',
},
};
diff --git a/docs/v5-upgrade.md b/docs/v5-upgrade.md
index cd30ce455d..4a7f6b6cdd 100644
--- a/docs/v5-upgrade.md
+++ b/docs/v5-upgrade.md
@@ -101,7 +101,7 @@ View [Theme Classes](themes.md?id=classes) for more details.
-
+
```
**Note:** If you're using additional Docsify plugins (such as emoji, external-script, front-matter, etc.), you'll need to update those URLs as well following the same pattern:
@@ -115,7 +115,6 @@ View [Theme Classes](themes.md?id=classes) for more details.
- **CDN Path**: Changed from `/lib/` to `/dist/`
- **Version**: Updated from `@4` to `@5`
- **Themes**: v5 uses a core theme (with optional add-ons available)
-- **Plugin Names**: `zoom-image` โ `zoom`
## Additional Notes
diff --git a/package-lock.json b/package-lock.json
index 387390f197..d5e8ec87fc 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -32,7 +32,7 @@
"@types/eslint": "^8.40.2",
"@types/prismjs": "^1.26.5",
"axios": "^1.5.0",
- "browser-sync": "^3.0.2",
+ "browser-sync": "^3.0.4",
"cross-env": "^10.0.0",
"cssnano": "^8.0.2",
"eslint": "^9.3.0",
@@ -15181,9 +15181,9 @@
"dev": true
},
"node_modules/nanoid": {
- "version": "3.3.12",
- "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz",
- "integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==",
+ "version": "3.3.16",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.16.tgz",
+ "integrity": "sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==",
"dev": true,
"funding": [
{
@@ -15908,9 +15908,9 @@
}
},
"node_modules/postcss": {
- "version": "8.5.15",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz",
- "integrity": "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==",
+ "version": "8.5.23",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.23.tgz",
+ "integrity": "sha512-g50586zr4bZmwFiTlflMu8E0bDTb5I5gertgwAKmsdUlTQIhZtunzUlD1WSzwcVWPoAVpsrA6vlfCD7oXvRwgg==",
"dev": true,
"funding": [
{
@@ -15928,7 +15928,7 @@
],
"license": "MIT",
"dependencies": {
- "nanoid": "^3.3.12",
+ "nanoid": "^3.3.16",
"picocolors": "^1.1.1",
"source-map-js": "^1.2.1"
},
diff --git a/src/core/config.js b/src/core/config.js
index b2e2fdb9e2..2648a9824e 100644
--- a/src/core/config.js
+++ b/src/core/config.js
@@ -58,6 +58,7 @@ const defaultDocsifyConfig = () => ({
skipLink: /** @type {false | string | Record} */ (
'Skip to main content'
),
+ sidebarPosition: /** @type {'left' | 'right'} */ ('left'),
subMaxLevel: 0,
vueComponents: /** @type {Record} */ ({}),
vueGlobalOptions: /** @type {Record} */ ({}),
diff --git a/src/core/event/index.js b/src/core/event/index.js
index 8395761430..ad194647c5 100644
--- a/src/core/event/index.js
+++ b/src/core/event/index.js
@@ -504,12 +504,10 @@ export function Events(Base) {
href = stripUrlExceptId(href);
const oldActive = dom.find(sidebar, 'li.active');
- const newActive = dom
- .find(
- sidebar,
- `a[href="${href}"], a[href="${decodeURIComponent(/** @type {string} */ (href))}"]`,
- )
- ?.closest('li');
+ const sidebarSelector = `.sidebar-nav a[href="${href}"], .sidebar-nav a[href="${decodeURIComponent(
+ /** @type {string} */ (href),
+ )}"]`;
+ const newActive = dom.find(sidebar, sidebarSelector)?.closest('li');
if (newActive && newActive !== oldActive) {
oldActive?.classList.remove('active');
diff --git a/src/core/render/index.js b/src/core/render/index.js
index f4db193754..94f3316fc8 100644
--- a/src/core/render/index.js
+++ b/src/core/render/index.js
@@ -324,8 +324,12 @@ export function Render(Base) {
this.#addTextAsTitleAttribute('.sidebar-nav a');
if (loadSidebar && activeEl) {
- const parent = /** @type {HTMLElement} */ (activeEl.parentElement);
- parent.innerHTML += this.compiler.subSidebar(subMaxLevel) || '';
+ activeEl
+ .closest('li')
+ ?.insertAdjacentHTML(
+ 'beforeend',
+ this.compiler.subSidebar(subMaxLevel) || '',
+ );
} else {
this.compiler.resetToc();
}
diff --git a/src/core/render/slugify.js b/src/core/render/slugify.js
index 6f1f6a7ee2..825011779b 100644
--- a/src/core/render/slugify.js
+++ b/src/core/render/slugify.js
@@ -23,7 +23,7 @@ export function slugify(str) {
.replace(/^(\d)/, '_$1');
let count = cache[slug];
- count = Object.keys(cache).includes(slug) ? count + 1 : 0;
+ count = Object.prototype.hasOwnProperty.call(cache, slug) ? count + 1 : 0;
cache[slug] = count;
if (count) {
diff --git a/src/core/render/tpl.js b/src/core/render/tpl.js
index 88b732a78f..b4c6de3b5c 100644
--- a/src/core/render/tpl.js
+++ b/src/core/render/tpl.js
@@ -36,18 +36,20 @@ export function corner(data, cornerExternalLinkTarget) {
* @returns {String} HTML of the main content
*/
export function main(config) {
- const { hideSidebar, name } = config;
+ const { hideSidebar, name, sidebarPosition } = config;
+ const sidebarPositionClass =
+ sidebarPosition === 'right' ? ' sidebar-right' : '';
// const name = config.name ? config.name : '';
const aside = /* html */ hideSidebar
? ''
: `
-