diff --git a/docs/guide/asset-handling.md b/docs/guide/asset-handling.md index dd6105a4..2ca33ddd 100644 --- a/docs/guide/asset-handling.md +++ b/docs/guide/asset-handling.md @@ -22,6 +22,11 @@ Assets placed in `public` will be copied to the root of the dist directory as-is 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. Contrast these two links: + +- [/pure.html](/pure.html) +- + ## 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/public/pure.html b/docs/public/pure.html new file mode 100644 index 00000000..0d0ecb5a --- /dev/null +++ b/docs/public/pure.html @@ -0,0 +1,12 @@ + + + + Plain HTML page | VitePress + + + + +

Not part of the main VitePress docs site

+
This page is plain HTML in the public directory.
+ + diff --git a/src/client/theme-default/support/utils.ts b/src/client/theme-default/support/utils.ts index 33bc0bb5..bf2ee19b 100644 --- a/src/client/theme-default/support/utils.ts +++ b/src/client/theme-default/support/utils.ts @@ -1,6 +1,6 @@ import { ref } from 'vue' import { withBase, useData } from 'vitepress' -import { EXTERNAL_URL_RE } from '../../shared.js' +import { EXTERNAL_URL_RE, PATHNAME_PROTOCOL_RE } from '../../shared.js' export const HASH_RE = /#.*$/ export const EXT_RE = /(index)?\.(md|html)$/ @@ -71,7 +71,7 @@ export function normalize(path: string): string { export function normalizeLink(url: string): string { if (isExternal(url)) { - return url + return url.replace(PATHNAME_PROTOCOL_RE, '') } const { site } = useData() diff --git a/src/node/markdown/plugins/link.ts b/src/node/markdown/plugins/link.ts index 46f54fd1..cb83c40f 100644 --- a/src/node/markdown/plugins/link.ts +++ b/src/node/markdown/plugins/link.ts @@ -5,7 +5,7 @@ import MarkdownIt from 'markdown-it' import type { MarkdownEnv } from '../env' import { URL } from 'url' -import { EXTERNAL_URL_RE } from '../../shared' +import { EXTERNAL_URL_RE, PATHNAME_PROTOCOL_RE } from '../../shared' const indexRE = /(^|.*\/)index.md(#?.*)$/i @@ -35,6 +35,7 @@ export const linkPlugin = ( if (url.replace(EXTERNAL_URL_RE, '').startsWith('//localhost:')) { pushLink(url, env) } + hrefAttr[1] = url.replace(PATHNAME_PROTOCOL_RE, '') } else if ( // internal anchor links !url.startsWith('#') && diff --git a/src/shared/shared.ts b/src/shared/shared.ts index 5789a611..4682c44f 100644 --- a/src/shared/shared.ts +++ b/src/shared/shared.ts @@ -18,6 +18,7 @@ export type { } from '../../types/shared.js' export const EXTERNAL_URL_RE = /^[a-z]+:/i +export const PATHNAME_PROTOCOL_RE = /^pathname:\/\// export const APPEARANCE_KEY = 'vitepress-theme-appearance' export const inBrowser = typeof window !== 'undefined'