diff --git a/docs/guide/asset-handling.md b/docs/guide/asset-handling.md index 2f62569d..7d2ce57a 100644 --- a/docs/guide/asset-handling.md +++ b/docs/guide/asset-handling.md @@ -26,25 +26,6 @@ Assets placed in `public` will be copied to the root of the output directory as- Note that you should reference files placed in `public` using root absolute path - for example, `public/icon.png` should always be referenced in source code as `/icon.png`. -There is one exception to this: if you have an HTML page in `public` and link to it from the main site, the router will yield a 404 by default. To get around this, VitePress provides a `pathname://` protocol which allows you to link to another page in the same domain as if the link is external. Compare these two links: - -- [/pure.html](/pure.html) -- - -Note that `pathname://` is only supported in Markdown links. Also, `pathname://` will open the link in a new tab by default. You can use `target="_self"` instead to open it in the same tab: - -**Input** - -```md -[Link to pure.html](/pure.html){target="_self"} - - -``` - -**Output** - -[Link to pure.html](/pure.html){target="_self"} - ## Base URL If your site is deployed to a non-root URL, you will need to set the `base` option in `.vitepress/config.js`. For example, if you plan to deploy your site to `https://foo.github.io/bar/`, then `base` should be set to `'/bar/'` (it should always start and end with a slash). diff --git a/docs/guide/routing.md b/docs/guide/routing.md index f5fa9bff..641807e4 100644 --- a/docs/guide/routing.md +++ b/docs/guide/routing.md @@ -93,7 +93,33 @@ You can use both absolute and relative paths when linking between pages. Note th [Getting Started](./getting-started.html) ``` -Learn more about linking to assets such images in [Asset Handling](asset-handling). +Learn more about linking to assets such images in [Asset Handling](./asset-handling). + +### Linking to Non-VitePress Pages + +If you want to link to a page in your site that is not generated by VitePress, you'll either need to use the full URL (opens in a new tab) or explicitly specify the target: + +**Input** + +```md +[Link to pure.html](/pure.html){target="_self"} +``` + +**Output** + +[Link to pure.html](/pure.html){target="_self"} + +::: tip Note + +In Markdown links, the `base` is automatically prepended to the URL. This means that if you want to link to a page outside of your base, you'd need something like `../../pure.html` in the link (resolved relative to the current page by the browser). + +Alternatively, you can directly use the anchor tag syntax: + +```md +Link to pure.html +``` + +::: ## Generating Clean URL diff --git a/src/client/app/utils.ts b/src/client/app/utils.ts index 9935284d..5028483c 100644 --- a/src/client/app/utils.ts +++ b/src/client/app/utils.ts @@ -22,8 +22,11 @@ export function joinPath(base: string, path: string) { return `${base}${path}`.replace(/\/+/g, '/') } +/** + * Append base to internal (non-relative) urls + */ export function withBase(path: string) { - return EXTERNAL_URL_RE.test(path) || path.startsWith('.') + return EXTERNAL_URL_RE.test(path) || !path.startsWith('/') ? path : joinPath(siteDataRef.value.base, path) } diff --git a/src/client/theme-default/support/utils.ts b/src/client/theme-default/support/utils.ts index e5fa8bca..3d05e9f5 100644 --- a/src/client/theme-default/support/utils.ts +++ b/src/client/theme-default/support/utils.ts @@ -1,25 +1,18 @@ import { withBase } from 'vitepress' import { useData } from '../composables/data' -import { isExternal, PATHNAME_PROTOCOL_RE } from '../../shared' +import { isExternal } from '../../shared' export function throttleAndDebounce(fn: () => void, delay: number): () => void { let timeoutId: NodeJS.Timeout let called = false return () => { - if (timeoutId) { - clearTimeout(timeoutId) - } + if (timeoutId) clearTimeout(timeoutId) if (!called) { fn() - called = true - setTimeout(() => { - called = false - }, delay) - } else { - timeoutId = setTimeout(fn, delay) - } + ;(called = true) && setTimeout(() => (called = false), delay) + } else timeoutId = setTimeout(fn, delay) } } @@ -28,9 +21,7 @@ export function ensureStartingSlash(path: string): string { } export function normalizeLink(url: string): string { - if (isExternal(url)) { - return url.replace(PATHNAME_PROTOCOL_RE, '') - } + if (isExternal(url)) return url const { site } = useData() const { pathname, search, hash } = new URL(url, 'http://a.com') diff --git a/src/node/markdown/plugins/link.ts b/src/node/markdown/plugins/link.ts index 220071a1..9aa29c96 100644 --- a/src/node/markdown/plugins/link.ts +++ b/src/node/markdown/plugins/link.ts @@ -4,12 +4,7 @@ import type MarkdownIt from 'markdown-it' import { URL } from 'url' -import { - EXTERNAL_URL_RE, - PATHNAME_PROTOCOL_RE, - isExternal, - type MarkdownEnv -} from '../../shared' +import { EXTERNAL_URL_RE, isExternal, type MarkdownEnv } from '../../shared' const indexRE = /(^|.*\/)index.md(#?.*)$/i @@ -38,7 +33,7 @@ export const linkPlugin = ( if (url.replace(EXTERNAL_URL_RE, '').startsWith('//localhost:')) { pushLink(url, env) } - hrefAttr[1] = url.replace(PATHNAME_PROTOCOL_RE, '') + hrefAttr[1] = url } else { if ( // internal anchor links diff --git a/src/shared/shared.ts b/src/shared/shared.ts index 3215cb49..9bc2de00 100644 --- a/src/shared/shared.ts +++ b/src/shared/shared.ts @@ -15,7 +15,6 @@ export type { } from '../../types/shared' export const EXTERNAL_URL_RE = /^[a-z]+:/i -export const PATHNAME_PROTOCOL_RE = /^pathname:\/\// export const APPEARANCE_KEY = 'vitepress-theme-appearance' export const HASH_RE = /#.*$/ export const EXT_RE = /(index)?\.(md|html)$/