Merge branch 'main' into doc-zh

pull/2249/head
vanch 3 years ago
commit c045f5b16e

@ -37,7 +37,7 @@ body:
attributes:
label: System Info
description: Output of `npx envinfo --system --npmPackages vitepress --binaries --browsers`
render: sh
render: Text
placeholder: System, Binaries, Browsers
validations:
required: true

@ -0,0 +1,15 @@
name: Close stale issues and PRs
on:
workflow_dispatch:
jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v8
with:
days-before-stale: 30
days-before-close: -1
stale-issue-label: stale
stale-pr-label: stale
operations-per-run: 1000

@ -23,7 +23,7 @@ jobs:
strategy:
matrix:
node_version: [16, 18, 20]
node_version: [18, 20, 21]
steps:
- name: Checkout

@ -1,3 +1,232 @@
# [1.0.0-rc.24](https://github.com/vuejs/vitepress/compare/v1.0.0-rc.23...v1.0.0-rc.24) (2023-10-24)
### Bug Fixes
- lock plugin-vue version ([aa75fd6](https://github.com/vuejs/vitepress/commit/aa75fd62643d51be647f6e5937c97b7c47bf9739))
- **styles:** large blur radius is causing color issues with safari ([a31e143](https://github.com/vuejs/vitepress/commit/a31e143afac597034a8d77f516961b0d2857ac8d))
### Features
- **template:** add types for theme config ([#3122](https://github.com/vuejs/vitepress/issues/3122)) ([56b3ce5](https://github.com/vuejs/vitepress/commit/56b3ce5032b1d3bcfd66a1a397d87172a6f113d7))
# [1.0.0-rc.23](https://github.com/vuejs/vitepress/compare/v1.0.0-rc.22...v1.0.0-rc.23) (2023-10-22)
### Bug Fixes
- don't normalize non-html/non-http links ([#3114](https://github.com/vuejs/vitepress/issues/3114)) ([da3d781](https://github.com/vuejs/vitepress/commit/da3d7812a143e3aa360845b89f573d4e1ec637dd))
- **mpa:** properly emit assets in mpa mode ([#3115](https://github.com/vuejs/vitepress/issues/3115)) ([6cf1de5](https://github.com/vuejs/vitepress/commit/6cf1de5e9e15d4507054744b665ac15d5f9a05f1))
- **theme/search:** prevent reactivity loss with i18n ([#3121](https://github.com/vuejs/vitepress/issues/3121)) ([50d61fa](https://github.com/vuejs/vitepress/commit/50d61faefacc3885efe99fe5477a3b815354a0c4))
# [1.0.0-rc.22](https://github.com/vuejs/vitepress/compare/v1.0.0-rc.21...v1.0.0-rc.22) (2023-10-15)
### Bug Fixes
- fixes a regression related with nanoid v5 ([#3090](https://github.com/vuejs/vitepress/issues/3090))
# [1.0.0-rc.21](https://github.com/vuejs/vitepress/compare/v1.0.0-rc.20...v1.0.0-rc.21) (2023-10-12)
### Bug Fixes
- **build:** handle .mjs/.mts files as data / path loaders ([#3058](https://github.com/vuejs/vitepress/issues/3058)) ([7991180](https://github.com/vuejs/vitepress/commit/7991180080366f9eb0d43fe95d25b53cf7af652c))
- **client:** only update head if needed ([#3017](https://github.com/vuejs/vitepress/issues/3017)) ([f2fc3dc](https://github.com/vuejs/vitepress/commit/f2fc3dc51b8019c18d5ab70a6b55b8333c91045a))
- **theme:** search's configuration about buttonAriaLabel doesn't work ([#3070](https://github.com/vuejs/vitepress/issues/3070)) ([c08bd46](https://github.com/vuejs/vitepress/commit/c08bd46aa757e7a0bc28b2318fb38037d583b27d))
### Features
- **md:** allow customizing container titles globally ([#3044](https://github.com/vuejs/vitepress/issues/3044)) ([bdb0800](https://github.com/vuejs/vitepress/commit/bdb080093f95ec43d013ea2ad537e567bdbb5a44))
# [1.0.0-rc.20](https://github.com/vuejs/vitepress/compare/v1.0.0-rc.15...v1.0.0-rc.20) (2023-09-24)
### Bug Fixes
- **build:** consistent route.path across dev and ssr ([#2997](https://github.com/vuejs/vitepress/issues/2997)) ([0d56855](https://github.com/vuejs/vitepress/commit/0d56855b54a97d4350485ee76c07a040fdc5738c))
- **build:** don't show missing lang warnings with text specifiers in fences ([aa40cec](https://github.com/vuejs/vitepress/commit/aa40cecd48942506ffb063863c9b054e66f1d79e))
- handle references in container titles ([7fbfe71](https://github.com/vuejs/vitepress/commit/7fbfe71b6cab2f091ba3d0c47a401fdc612b88b6)), closes [#3004](https://github.com/vuejs/vitepress/issues/3004)
- **hmr:** handle hmr in imported code snippets ([#3005](https://github.com/vuejs/vitepress/issues/3005)) ([e84f313](https://github.com/vuejs/vitepress/commit/e84f31371e9e5219d46ae58151667d24e12b77bb))
- snippet hmr not working with rewrites ([a275049](https://github.com/vuejs/vitepress/commit/a2750492be7869ed48a5bde1ffbc177093356758))
- selectively pass env for container titles ([1a9c32d](https://github.com/vuejs/vitepress/commit/1a9c32df12388386877c50daf9fc7924888eac07)), closes [#3007](https://github.com/vuejs/vitepress/issues/3007)
- **types:** add RegExp to markdown's allowed attributes ([#3008](https://github.com/vuejs/vitepress/issues/3008)) ([bc96b2b](https://github.com/vuejs/vitepress/commit/bc96b2bb5bc5361e55c46f270e3759c513db65d3))
# [1.0.0-rc.15](https://github.com/vuejs/vitepress/compare/v1.0.0-rc.14...v1.0.0-rc.15) (2023-09-20)
### Bug Fixes
- **build:** allow using symlinks with code snippets ([f186901](https://github.com/vuejs/vitepress/commit/f186901a5157c904b3593089d72f2bad3530e7a3)), closes [#1617](https://github.com/vuejs/vitepress/issues/1617)
- **build:** handle importing code snippets not having an extension ([#2978](https://github.com/vuejs/vitepress/issues/2978)) ([e99aaad](https://github.com/vuejs/vitepress/commit/e99aaad9cf8ab3661e609cd2cf6ac7da57cb7eb5))
- **build:** indentation being lost in code blocks ([5bb6bb0](https://github.com/vuejs/vitepress/commit/5bb6bb0a147ad43ca2d7069aad50fb9c6c2c11d6)), closes [#2988](https://github.com/vuejs/vitepress/issues/2988)
- **compat:** reset setRawMode on process exit ([#2994](https://github.com/vuejs/vitepress/issues/2994)) ([70fe47c](https://github.com/vuejs/vitepress/commit/70fe47c1dd69d39a40c83e919324d2b71f19bdaa))
### Features
- allow passing fast glob options to `createContentLoader` ([4f9a60b](https://github.com/vuejs/vitepress/commit/4f9a60b0cfa2fa841465f6e8cc5f77ed3e023817)), closes [#2985](https://github.com/vuejs/vitepress/issues/2985)
# [1.0.0-rc.14](https://github.com/vuejs/vitepress/compare/v1.0.0-rc.13...v1.0.0-rc.14) (2023-09-16)
### Bug Fixes
- **client:** router in invalid state after 404 ([#2972](https://github.com/vuejs/vitepress/issues/2972)) ([28ef0ea](https://github.com/vuejs/vitepress/commit/28ef0ea6f60ab33e9cf34ecef10e1515d84f7168))
- **client:** scripts loading out of order when added through head ([#2970](https://github.com/vuejs/vitepress/issues/2970)) ([98679c9](https://github.com/vuejs/vitepress/commit/98679c9e82fcd3bbe3829640d0386cbd730e61ba))
- customizing the starting line number even if globally set ([#2941](https://github.com/vuejs/vitepress/issues/2941)) ([0cd87b1](https://github.com/vuejs/vitepress/commit/0cd87b1bafa6158ded0bf741553816f3d9b43a89))
- make algolia search work with indices that don't return absolute urls ([#2956](https://github.com/vuejs/vitepress/issues/2956)) ([2a34c6b](https://github.com/vuejs/vitepress/commit/2a34c6b3076bf418b3abbbca984fcb033743a611)), closes [#336](https://github.com/vuejs/vitepress/issues/336) [#805](https://github.com/vuejs/vitepress/issues/805)
- **theme:** remove extra padding from top when navbar is hidden ([#2575](https://github.com/vuejs/vitepress/issues/2575)) ([fd46dc9](https://github.com/vuejs/vitepress/commit/fd46dc9b8f8951b3196e4208d958d1ca0e1dc6e8))
### Features
- mathjax support ([#2977](https://github.com/vuejs/vitepress/issues/2977)) ([7271a95](https://github.com/vuejs/vitepress/commit/7271a959480261d60c01146d2e520d0f662e0380))
- **theme:** allow forcing dark mode ([#2974](https://github.com/vuejs/vitepress/issues/2974)) ([1fb5d22](https://github.com/vuejs/vitepress/commit/1fb5d228a269e913163246e988806056b3f1b9d9))
- **theme:** allow forcing site locale in last updated format ([#2973](https://github.com/vuejs/vitepress/issues/2973)) ([a18e5e4](https://github.com/vuejs/vitepress/commit/a18e5e48a442b09487cda8ab14e3b103ce270641))
# [1.0.0-rc.13](https://github.com/vuejs/vitepress/compare/v1.0.0-rc.12...v1.0.0-rc.13) (2023-09-13)
### Bug Fixes
- **theme:** allow wrapping feature icons ([a1e1267](https://github.com/vuejs/vitepress/commit/a1e1267549e198b35455d055536cd0c6d1ad79ce)), closes [#2923](https://github.com/vuejs/vitepress/issues/2923)
- **theme:** local search enter key with the search result ([#2937](https://github.com/vuejs/vitepress/issues/2937)) ([00ef2f1](https://github.com/vuejs/vitepress/commit/00ef2f1db0369f50b3b634508e798b19b9525b34))
### Features
- **theme:** add search insights boolean to algolia search ([#2940](https://github.com/vuejs/vitepress/issues/2940)) ([32aa2a7](https://github.com/vuejs/vitepress/commit/32aa2a7d179049e5a1ed809018c32418bf69e8d5))
### Reverts
- Revert "feat(theme): use inert to avoid traverse menus and content with keyboard" (#2953) ([54891df](https://github.com/vuejs/vitepress/commit/54891df6149f4d0a871b16edf5f9a8a6fec639f9)), closes [#2953](https://github.com/vuejs/vitepress/issues/2953) [#2932](https://github.com/vuejs/vitepress/issues/2932)
# [1.0.0-rc.12](https://github.com/vuejs/vitepress/compare/v1.0.0-rc.11...v1.0.0-rc.12) (2023-09-10)
### Bug Fixes
- **theme:** prevent closing local search box on key enter ([#2933](https://github.com/vuejs/vitepress/issues/2933)) ([e544b41](https://github.com/vuejs/vitepress/commit/e544b411d91eba54154243b0af4cea3226c192c4))
- **theme:** use brand color on search highlight ([dfc0fbf](https://github.com/vuejs/vitepress/commit/dfc0fbfcb4f255461bd90aef23a3dda1422b8335)), closes [#2902](https://github.com/vuejs/vitepress/issues/2902)
### Features
- highlight nav by default when one of the items is matched ([#2893](https://github.com/vuejs/vitepress/issues/2893)) ([b1fbece](https://github.com/vuejs/vitepress/commit/b1fbece047ca503f2c59553f9e37a0aac4be52c9))
- process md includes before building local search index ([#2906](https://github.com/vuejs/vitepress/issues/2906)) ([c6ff5c7](https://github.com/vuejs/vitepress/commit/c6ff5c76867dc59d5548cb33fd8447e23712bef5))
- support for customizing the starting line number in a code block ([#2917](https://github.com/vuejs/vitepress/issues/2917)) ([c0ce7f7](https://github.com/vuejs/vitepress/commit/c0ce7f723e52682d9ca107e4ce4e0e5c82710e02))
- **theme:** allow setting target in home features ([#2897](https://github.com/vuejs/vitepress/issues/2897)) ([cb49673](https://github.com/vuejs/vitepress/commit/cb4967313e5edcfd4bfc12aa10e75fec7b32e0c8))
- **theme:** use inert to avoid traverse menus and content with keyboard ([#2932](https://github.com/vuejs/vitepress/issues/2932)) ([070fc0a](https://github.com/vuejs/vitepress/commit/070fc0a56ddb941e26a098ba7207b5d1e91b7b51))
# [1.0.0-rc.11](https://github.com/vuejs/vitepress/compare/v1.0.0-rc.10...v1.0.0-rc.11) (2023-09-10)
### Bug Fixes
- **init:** missing mts extension on windows ([195ebe9](https://github.com/vuejs/vitepress/commit/195ebe9464e2cc9b208e7d6c8bc5fa9f92025fdc)), closes [#2886](https://github.com/vuejs/vitepress/issues/2886)
- respect attrs on custom containers ([8b76167](https://github.com/vuejs/vitepress/commit/8b76167ccfbe5bf21295db6905451e1c50ca4407))
- temp workaround for broken navigation from 404 to home ([a18d544](https://github.com/vuejs/vitepress/commit/a18d5447f29f05d75bf0e20ff839e5c3bcdac390)), closes [#2891](https://github.com/vuejs/vitepress/issues/2891)
- **theme:** dropdown menu partially hidden by the homepage footer when it is too long ([#2904](https://github.com/vuejs/vitepress/issues/2904)) ([a60f079](https://github.com/vuejs/vitepress/commit/a60f079f996cc8ce9aeb189a25187fdbce2217ab))
- **theme:** improve contrast of search highlight text ([#2887](https://github.com/vuejs/vitepress/issues/2887)) ([20f9770](https://github.com/vuejs/vitepress/commit/20f97702680b47eb9675770df4db94a3e3b94ef1))
- **theme:** link hover color inside a custom block ([#2876](https://github.com/vuejs/vitepress/issues/2876)) ([39784ca](https://github.com/vuejs/vitepress/commit/39784ca55fdbefa97b7e9f892609ef8bdaeadf50))
- **theme:** prevent layout shift in search button key ([#2889](https://github.com/vuejs/vitepress/issues/2889)) ([0088434](https://github.com/vuejs/vitepress/commit/0088434895e5df9afea5bb8e81c515a41e824c44))
- **theme:** search button key misplaced on safari ([18adc07](https://github.com/vuejs/vitepress/commit/18adc07117cbf151b51aa205419496938a322a2e))
- **types:** NavItem can only have either link or items ([#2880](https://github.com/vuejs/vitepress/issues/2880)) ([12ef12d](https://github.com/vuejs/vitepress/commit/12ef12d6330f61a29102e7a0d537e742ff20367f))
### Features
- detect bun package manager ([#2874](https://github.com/vuejs/vitepress/issues/2874)) ([83270fe](https://github.com/vuejs/vitepress/commit/83270fe65767016a98cd59b6256f1361439cc7c8))
- skip rendering if env.BUNDLE_ONLY is truthy ([#2890](https://github.com/vuejs/vitepress/issues/2890)) ([d40eb19](https://github.com/vuejs/vitepress/commit/d40eb1903be022c9dfe10136122f5dc5aacb71d3))
# [1.0.0-rc.10](https://github.com/vuejs/vitepress/compare/v1.0.0-rc.9...v1.0.0-rc.10) (2023-08-28)
### Bug Fixes
- pseudo styles being removed with postcssIsolateStyles ([21b4f8c](https://github.com/vuejs/vitepress/commit/21b4f8caad8f0b9a570f00ac2662635062db8566)), closes [#2868](https://github.com/vuejs/vitepress/issues/2868) [#2867](https://github.com/vuejs/vitepress/issues/2867)
- resolve snippets from original file path - align with include behavior ([8aa032f](https://github.com/vuejs/vitepress/commit/8aa032f60cd52e674a401f79b3cb473ac7d22abb))
### Features
- allow overriding mdit-vue/component options ([4f01f1a](https://github.com/vuejs/vitepress/commit/4f01f1a09c84fced276e1a138a59ed1b9679ce15))
### Reverts
- "fix: createContentLoader generates invalid url when sets `base`" ([#2865](https://github.com/vuejs/vitepress/issues/2865)) ([6be5a7e](https://github.com/vuejs/vitepress/commit/6be5a7e830fab2361bde5a4194930b2898733a8b))
# [1.0.0-rc.9](https://github.com/vuejs/vitepress/compare/v1.0.0-rc.4...v1.0.0-rc.9) (2023-08-28)
### Bug Fixes
- **a11y/theme:** disable transitions if user prefers reduced motion ([fc5092f](https://github.com/vuejs/vitepress/commit/fc5092fb651487e69737fff04d3979f00c67dcc6))
- **build:** respect preserveSymlinks ([#2780](https://github.com/vuejs/vitepress/issues/2780)) ([1bda710](https://github.com/vuejs/vitepress/commit/1bda710702f5569e26b24b44785d938296870884))
- **cli/init:** print the correct packageManager ([#2787](https://github.com/vuejs/vitepress/issues/2787)) ([b388b0a](https://github.com/vuejs/vitepress/commit/b388b0a8c169e399f8da43368022454b6e8ea489))
- **cli/init:** terminal message has not enough contrast ([#2786](https://github.com/vuejs/vitepress/issues/2786)) ([4d9d977](https://github.com/vuejs/vitepress/commit/4d9d9775190178d0eaea5b3cea86309ae420bd43))
- restart server on theme creation/deletion ([#2785](https://github.com/vuejs/vitepress/issues/2785)) ([e0be677](https://github.com/vuejs/vitepress/commit/e0be677554a517e8b02fcaf930828bb052d1c4a4))
- scroll-to-top in iOS when opens sidebar ([#2803](https://github.com/vuejs/vitepress/issues/2803)) ([3dab9a6](https://github.com/vuejs/vitepress/commit/3dab9a6be1b543cf52c7c61f1e439a7973cd6667))
- stackblitz not working on firefox ([877f643](https://github.com/vuejs/vitepress/commit/877f643b133b70f01bbf397900829050a399893f)), closes [#2817](https://github.com/vuejs/vitepress/issues/2817)
- **theme:** docsearch variables not applying properly on ios beta ([436e99a](https://github.com/vuejs/vitepress/commit/436e99a594d42650f69c062fd095eb0502a76b34))
- **theme:** improve logo svg and add `art` dir ([1f8c58a](https://github.com/vuejs/vitepress/commit/1f8c58aed0bf5a191021913dd7f9a87e9b75f3eb))
- **theme:** prevent sidebar re-render unless there is actual change ([33962e0](https://github.com/vuejs/vitepress/commit/33962e04ebb2724e12b131f61ff00fe0aaf990f3)), closes [#2796](https://github.com/vuejs/vitepress/issues/2796)
- **theme:** revert 79 to 179 in yellow-soft ([#2858](https://github.com/vuejs/vitepress/issues/2858)) ([74fcb60](https://github.com/vuejs/vitepress/commit/74fcb60fb4ceb97b9ab0442a26e22a726af2dcc9))
- **theme:** show only one carbon ad at a time ([5ced0cc](https://github.com/vuejs/vitepress/commit/5ced0cca837ac7fbf1884ab56255b29c69dbec40))
- **theme:** ssr issues on deno ([e8edd0a](https://github.com/vuejs/vitepress/commit/e8edd0a05f43491656c00db36630f391caf64461))
### Features
- allow customizing markdown renderer used for local search indexing ([#2770](https://github.com/vuejs/vitepress/issues/2770)) ([00dc1e6](https://github.com/vuejs/vitepress/commit/00dc1e6742273fe6fde74e7abbd160bd7724af4d))
- export postcssIsolateStyles for vp-raw ([3c736c1](https://github.com/vuejs/vitepress/commit/3c736c1c95814d1ca43b4e99bda62b8ccc908cd5))
- **theme:** allow overriding code copied text from css ([#2833](https://github.com/vuejs/vitepress/issues/2833)) ([e8ef1aa](https://github.com/vuejs/vitepress/commit/e8ef1aaabecd7374cdf6cefca6b02ff9d3d3573f))
- **theme:** allow overriding last updated time in doc footer from frontmatter ([#2848](https://github.com/vuejs/vitepress/issues/2848)) ([9a062a6](https://github.com/vuejs/vitepress/commit/9a062a6dd63db3dc9d951f2973c4ab606594a11f))
- **theme:** allow providing custom `toggle-appearance` function ([#2844](https://github.com/vuejs/vitepress/issues/2844)) ([a5f2eac](https://github.com/vuejs/vitepress/commit/a5f2eacf225ff1a9a82c10ae492658190f313fb0))
- **theme:** allow setting rel and target on sidebar links ([e477cdf](https://github.com/vuejs/vitepress/commit/e477cdfd2f62144cd6331f45aaaa865185a64575)), closes [#2851](https://github.com/vuejs/vitepress/issues/2851)
- **theme:** export VPButton and VPSponsors ([#2767](https://github.com/vuejs/vitepress/issues/2767)) ([6960ec1](https://github.com/vuejs/vitepress/commit/6960ec1cf61e973ffb238af2b77ad7aaf8c83500))
- **theme:** export VPImage ([#2814](https://github.com/vuejs/vitepress/issues/2814)) ([f242140](https://github.com/vuejs/vitepress/commit/f242140c47e8a15070f689d5a4e54c7d88100f96))
- **theme:** improve color system ([#2797](https://github.com/vuejs/vitepress/issues/2797)) ([e4f5c51](https://github.com/vuejs/vitepress/commit/e4f5c51bbe25d42fd52a1cd47e83dda4254fdd7e)), closes [#2100](https://github.com/vuejs/vitepress/issues/2100)
### BREAKING CHANGES
- `pathname://` protocol is dropped. Specify `target="_self"` or `target="_blank"` instead. Refer [docs](https://vitepress.dev/guide/routing#linking-to-non-vitepress-pages) to learn more.
- Shiki's default theme is now changed to `github-light` and `github-dark`. If you want to use the old theme, you can set `markdown.theme` in your config to `'material-theme-palenight'`.
- Internal logic of `isDark` is changed to use vueuse. It might impact your custom theme. You can customize its behavior using [`appearance`](https://vitepress.dev/reference/site-config#appearance) option.
- Default theme's color system is updated to make it more easily customizable. Refer the [PR](https://github.com/vuejs/vitepress/pull/2797) for new variables.
# [1.0.0-rc.4](https://github.com/vuejs/vitepress/compare/v1.0.0-beta.7...v1.0.0-rc.4) (2023-08-08)
### Bug Fixes
- `createContentLoader` generates invalid url when `base` is set ([#2714](https://github.com/vuejs/vitepress/issues/2714)) ([0f38eb4](https://github.com/vuejs/vitepress/commit/0f38eb440492f3a486517714976fbfe6dfb30a09))
- **build:** make outDir from cli work properly ([17378c0](https://github.com/vuejs/vitepress/commit/17378c064f3e6f166ce180f8d7eeced2f1cc4224)), closes [#2716](https://github.com/vuejs/vitepress/issues/2716)
- **build:** nested rewrites not working properly ([0f421d7](https://github.com/vuejs/vitepress/commit/0f421d72221495b8ef14195db3e3df9297ebc6ff))
- **client:** handle empty hash in links ([#2738](https://github.com/vuejs/vitepress/issues/2738)) ([c6c983e](https://github.com/vuejs/vitepress/commit/c6c983ed73a019027b452b3eaf0ee4b502d38818))
- fix sitemap path resolution ([481a5e3](https://github.com/vuejs/vitepress/commit/481a5e3cb55c6fda2c318180cfa0532ed34e4fc5)), closes [#2749](https://github.com/vuejs/vitepress/issues/2749)
- **theme:** align max-width media queries ([d31051a](https://github.com/vuejs/vitepress/commit/d31051a05106f97924be3cdb3919f24acc232b59))
- **theme:** allow using h1 headings in outline ([e3f8fc7](https://github.com/vuejs/vitepress/commit/e3f8fc7972f5506cd9def08ad13c62141737318f)), closes [#1529](https://github.com/vuejs/vitepress/issues/1529)
- **theme:** close dropdown menus after an item is clicked ([#2380](https://github.com/vuejs/vitepress/issues/2380)) ([e54eea3](https://github.com/vuejs/vitepress/commit/e54eea3da0de640e7b343381bddf9a439d638954))
- **theme:** don't reset scroll position on changing tab in code groups ([039798a](https://github.com/vuejs/vitepress/commit/039798a8c14a8c455e1187c5584c7f518c40f66a)), closes [#2732](https://github.com/vuejs/vitepress/issues/2732) [#2362](https://github.com/vuejs/vitepress/issues/2362)
- **theme:** dont show transparent navbar other than home ([#2742](https://github.com/vuejs/vitepress/issues/2742)) ([1d6254b](https://github.com/vuejs/vitepress/commit/1d6254b615b48ceef85267045e8fce976a7eafd5))
- **theme:** hide outline marker on scroll to top ([81e7405](https://github.com/vuejs/vitepress/commit/81e7405e193e832442db9aedb50ed3dc741e92ed))
- **theme:** outline marker flicks when navigating towards above ([e8ebf1b](https://github.com/vuejs/vitepress/commit/e8ebf1b0483e025b7d3bc3ea6eb3fa02d4acac93)), closes [#2665](https://github.com/vuejs/vitepress/issues/2665) [#2676](https://github.com/vuejs/vitepress/issues/2676)
- **theme:** override docsearch button bg ([063b0e5](https://github.com/vuejs/vitepress/commit/063b0e520a0b34db934371f56ddba212ceb3ba4c)), closes [#2735](https://github.com/vuejs/vitepress/issues/2735)
- **theme:** respect feature icon dimensions set from frontmatter ([93823a8](https://github.com/vuejs/vitepress/commit/93823a8566df22c57cb4fbc81fa65c34222ece5e)), closes [#1886](https://github.com/vuejs/vitepress/issues/1886)
- **theme:** scroll code group tab into view on selection ([1a6efba](https://github.com/vuejs/vitepress/commit/1a6efbae8e13eb6612aacdb8d384554e72e5f562)), closes [#2355](https://github.com/vuejs/vitepress/issues/2355)
- **theme:** update sidebar active link status on hash change ([#2736](https://github.com/vuejs/vitepress/issues/2736)) ([3840eaa](https://github.com/vuejs/vitepress/commit/3840eaae163cc9307c8d8525ad03c59752443b2b))
- **regression/theme:** fix sidebar collapsing ([#2753](https://github.com/vuejs/vitepress/issues/2753)) ([9a4ee07](https://github.com/vuejs/vitepress/commit/9a4ee07260191adeb4c3810d95b044439609525c))
- **cli:** generate mjs file on init if `"type": "module"` is not present ([23d7511](https://github.com/vuejs/vitepress/commit/23d751165f6def6fa6b3a5d7efd89b993a2780d8))
- **theme:** language menu undefined text ([#2755](https://github.com/vuejs/vitepress/issues/2755)) ([c9d4655](https://github.com/vuejs/vitepress/commit/c9d465587a3b2188ff9922483a15d7096e6a3e6c))
### Features
- **theme:** final re-brand ([#2727](https://github.com/vuejs/vitepress/pull/2727)) ([c0d838b](https://github.com/vuejs/vitepress/commit/c0d838bda0121fc162d1e6a43324f75290bc1b72))
- allow html blocks inside code groups ([#2719](https://github.com/vuejs/vitepress/issues/2719)) ([7f0c18e](https://github.com/vuejs/vitepress/commit/7f0c18e01384d48380b64ba629229ec048f85453))
- **build:** add `markdown.preConfig` option ([ce85726](https://github.com/vuejs/vitepress/commit/ce85726c127d9478274126374df9c37ee8b31167)), closes [#1382](https://github.com/vuejs/vitepress/issues/1382)
- **build:** allow overriding vite config loading ([#2750](https://github.com/vuejs/vitepress/issues/2750)) ([1bed154](https://github.com/vuejs/vitepress/commit/1bed154612661ac3783558cf82a7e94832ee4ff8))
- **client:** allow customizing scrollOffset padding ([20b509c](https://github.com/vuejs/vitepress/commit/20b509c6e1d957c73be75da27635b23de42781d4)), closes [#2739](https://github.com/vuejs/vitepress/issues/2739)
- **client:** allow overriding props on Content ([1179484](https://github.com/vuejs/vitepress/commit/11794844327c65bd6086b1237b0d6568cb32a4cb)), closes [#2712](https://github.com/vuejs/vitepress/issues/2712)
- i18n with sitemap ([#2708](https://github.com/vuejs/vitepress/issues/2708)) ([7778187](https://github.com/vuejs/vitepress/commit/7778187f2dc31554fa7541da9648235c994d4ae8))
- **search:** allow enabling detailed view by default ([4af5975](https://github.com/vuejs/vitepress/commit/4af597582cd8ae565e22c912f26f67123babcd61)), closes [#2690](https://github.com/vuejs/vitepress/issues/2690)
- **theme:** allow adding custom layouts ([f4a5c43](https://github.com/vuejs/vitepress/commit/f4a5c43cb00d70143cefcd9dfd9ba536f120ffda)), closes [#2547](https://github.com/vuejs/vitepress/issues/2547)
- **theme:** allow customizing default theme's 404 page ([d7e2254](https://github.com/vuejs/vitepress/commit/d7e225473bd072119c3ce76317db2b723be74f81)), closes [#2715](https://github.com/vuejs/vitepress/issues/2715)
- **theme:** allow customizing prev/next text from config file ([09a4fdc](https://github.com/vuejs/vitepress/commit/09a4fdc9b844a3e1877045afc496282b988f6f6b)), closes [#1373](https://github.com/vuejs/vitepress/issues/1373)
- **theme:** allow overriding logo link ([2a7422b](https://github.com/vuejs/vitepress/commit/2a7422bbbf91b852e27525d64627e9cff6eff294)), closes [#1683](https://github.com/vuejs/vitepress/issues/1683)
- **theme:** allow passing html in nav links ([69251b7](https://github.com/vuejs/vitepress/commit/69251b7484d8e4591841c32dd2f5a0179859cf14)), closes [#1652](https://github.com/vuejs/vitepress/issues/1652)
- **theme:** allow setting base path in sidebar items ([#2734](https://github.com/vuejs/vitepress/issues/2734)) ([52884d9](https://github.com/vuejs/vitepress/commit/52884d9d4b3ad294f4c4fcab637c4e07c80dde3a))
### Reverts
- [#2689](https://github.com/vuejs/vitepress/issues/2689) ([#2722](https://github.com/vuejs/vitepress/issues/2722)) ([a56d608](https://github.com/vuejs/vitepress/commit/a56d608bec427ad51a9edb620d8fb01ebae29550))
### BREAKING CHANGES
- Node v18+ is now required to run VitePress.
- VitePress now only provides ESM API. Refer [#2703](https://github.com/vuejs/vitepress/issues/2703) for details.
# [1.0.0-beta.7](https://github.com/vuejs/vitepress/compare/v1.0.0-beta.6...v1.0.0-beta.7) (2023-07-29)
### Bug Fixes

@ -1,4 +1,4 @@
# VitePress (beta) 📝💨
# VitePress (RC: release candidate) 📝💨
[![Test](https://github.com/vuejs/vitepress/workflows/Test/badge.svg)](https://github.com/vuejs/vitepress/actions)
[![npm](https://img.shields.io/npm/v/vitepress)](https://www.npmjs.com/package/vitepress)
@ -8,7 +8,7 @@
VitePress is [VuePress](https://vuepress.vuejs.org)' spiritual successor, built on top of [vite](https://github.com/vitejs/vite).
Currently, it is in the `beta` stage. It is already suitable for out-of-the-box documentation use. There still might be issues, however, we do not plan to introduce any breaking changes from here on until the stable release.
Currently, it is in the `release candidate` stage. It is already suitable for out-of-the-box documentation use. We do not plan to introduce any breaking changes from here on until the stable release.
## Documentation

@ -91,8 +91,11 @@ export default defineConfig({
search: {
provider: 'local',
options: {
exclude(relativePath) {
return relativePath.startsWith('local-search/excluded')
_render(src, env, md) {
const html = md.render(src, env)
if (env.frontmatter?.search === false) return ''
if (env.relativePath.startsWith('local-search/excluded')) return ''
return html
}
}
}

@ -1,7 +1,7 @@
# Static Data
<script setup lang="ts">
import { data } from './basic.data.js'
import { data } from './basic.data.mjs'
import { data as contentData } from './contentLoader.data.js'
</script>

@ -1,7 +1,7 @@
---
title: Multiple Levels Outline
editLink: true
outline: 'deep'
outline: deep
---
# h1 - 1

@ -163,19 +163,19 @@ describe('Line Numbers', () => {
describe('Import Code Snippets', () => {
test('basic', async () => {
const lines = page.locator('#basic-code-snippet + div code > span')
expect(await lines.count()).toBe(11)
expect(await lines.count()).toBe(22)
})
test('specify region', async () => {
const lines = page.locator('#specify-region + div code > span')
expect(await lines.count()).toBe(3)
expect(await lines.count()).toBe(6)
})
test('with other features', async () => {
const div = page.locator('#with-other-features + div')
expect(await getClassList(div)).toContain('line-numbers-mode')
const lines = div.locator('code > span')
expect(await lines.count()).toBe(3)
expect(await lines.count()).toBe(6)
expect(await getClassList(lines.nth(0))).toContain('highlighted')
})
})
@ -216,10 +216,10 @@ describe('Code Groups', () => {
// blocks
const blocks = div.locator('.blocks > div')
expect(await blocks.nth(0).locator('code > span').count()).toBe(11)
expect(await blocks.nth(0).locator('code > span').count()).toBe(22)
expect(await getClassList(blocks.nth(1))).toContain('line-numbers-mode')
expect(await getClassList(blocks.nth(1))).toContain('language-ts')
expect(await blocks.nth(1).locator('code > span').count()).toBe(3)
expect(await blocks.nth(1).locator('code > span').count()).toBe(6)
expect(
await getClassList(blocks.nth(1).locator('code > span').nth(0))
).toContain('highlighted')

@ -50,14 +50,14 @@ test.each(variations)('init %s', async (_, { theme, useTs }) => {
expect(await page.textContent('h1')).toMatch('My Awesome Project')
await page.click('a[href="/markdown-examples.html"]')
await page.waitForSelector('pre code')
await page.waitForFunction('document.querySelector("pre code")')
expect(await page.textContent('h1')).toMatch('Markdown Extension Examples')
await goto('/')
expect(await page.textContent('h1')).toMatch('My Awesome Project')
await page.click('a[href="/api-examples.html"]')
await page.waitForSelector('pre code')
await page.waitForFunction('document.querySelector("pre code")')
expect(await page.textContent('h1')).toMatch('Runtime API Examples')
// teardown

@ -28,15 +28,19 @@ describe('client/theme-default/support/sidebar', () => {
}
test('gets `/` sidebar', () => {
expect(getSidebar(normalSidebar, '/')).toBe(root)
expect(getSidebar(normalSidebar, '/')).toStrictEqual(root)
})
test('gets `/multi-sidebar/` sidebar', () => {
expect(getSidebar(normalSidebar, '/multi-sidebar/')).toBe(another)
expect(getSidebar(normalSidebar, '/multi-sidebar/')).toStrictEqual(
another
)
})
test('gets `/` sidebar again', () => {
expect(getSidebar(normalSidebar, '/some-entry.html')).toBe(root)
expect(getSidebar(normalSidebar, '/some-entry.html')).toStrictEqual(
root
)
})
})
@ -47,15 +51,19 @@ describe('client/theme-default/support/sidebar', () => {
}
test('gets `/` sidebar', () => {
expect(getSidebar(reversedSidebar, '/')).toBe(root)
expect(getSidebar(reversedSidebar, '/')).toStrictEqual(root)
})
test('gets `/multi-sidebar/` sidebar', () => {
expect(getSidebar(reversedSidebar, '/multi-sidebar/')).toBe(another)
expect(getSidebar(reversedSidebar, '/multi-sidebar/')).toStrictEqual(
another
)
})
test('gets `/` sidebar again', () => {
expect(getSidebar(reversedSidebar, '/some-entry.html')).toBe(root)
expect(getSidebar(reversedSidebar, '/some-entry.html')).toStrictEqual(
root
)
})
})
@ -74,19 +82,25 @@ describe('client/theme-default/support/sidebar', () => {
}
test('gets `/` sidebar', () => {
expect(getSidebar(nestedSidebar, '/')).toBe(root)
expect(getSidebar(nestedSidebar, '/')).toStrictEqual(root)
})
test('gets `/multi-sidebar/` sidebar', () => {
expect(getSidebar(nestedSidebar, '/multi-sidebar/')).toBe(another)
expect(getSidebar(nestedSidebar, '/multi-sidebar/')).toStrictEqual(
another
)
})
test('gets `/multi-sidebar/nested/` sidebar', () => {
expect(getSidebar(nestedSidebar, '/multi-sidebar/nested/')).toBe(nested)
expect(
getSidebar(nestedSidebar, '/multi-sidebar/nested/')
).toStrictEqual(nested)
})
test('gets `/` sidebar again', () => {
expect(getSidebar(nestedSidebar, '/some-entry.html')).toBe(root)
expect(getSidebar(nestedSidebar, '/some-entry.html')).toStrictEqual(
root
)
})
})
})

@ -1,4 +1,40 @@
import { dedent } from 'node/markdown/plugins/snippet'
import { dedent, rawPathToToken } from 'node/markdown/plugins/snippet'
const removeEmptyKeys = <T extends Record<string, unknown>>(obj: T) => {
return Object.fromEntries(
Object.entries(obj).filter(([, value]) => value !== '')
) as T
}
/* prettier-ignore */
const rawPathTokenMap: [string, Partial<{ filepath: string, extension: string, title: string, region: string, lines: string, lang: string }>][] = [
['/path/to/file.extension', { filepath: '/path/to/file.extension', extension: 'extension', title: 'file.extension' }],
['./path/to/file.extension', { filepath: './path/to/file.extension', extension: 'extension', title: 'file.extension' }],
['/path to/file.extension', { filepath: '/path to/file.extension', extension: 'extension', title: 'file.extension' }],
['./path to/file.extension', { filepath: './path to/file.extension', extension: 'extension', title: 'file.extension' }],
['/path.to/file.extension', { filepath: '/path.to/file.extension', extension: 'extension', title: 'file.extension' }],
['./path.to/file.extension', { filepath: './path.to/file.extension', extension: 'extension', title: 'file.extension' }],
['/path .to/file.extension', { filepath: '/path .to/file.extension', extension: 'extension', title: 'file.extension' }],
['./path .to/file.extension', { filepath: './path .to/file.extension', extension: 'extension', title: 'file.extension' }],
['/path/to/file', { filepath: '/path/to/file', title: 'file' }],
['./path/to/file', { filepath: './path/to/file', title: 'file' }],
['/path to/file', { filepath: '/path to/file', title: 'file' }],
['./path to/file', { filepath: './path to/file', title: 'file' }],
['/path.to/file', { filepath: '/path.to/file', title: 'file' }],
['./path.to/file', { filepath: './path.to/file', title: 'file' }],
['/path .to/file', { filepath: '/path .to/file', title: 'file' }],
['./path .to/file', { filepath: './path .to/file', title: 'file' }],
['/path/to/file.extension#region', { filepath: '/path/to/file.extension', extension: 'extension', title: 'file.extension', region: '#region' }],
['./path/to/file.extension {c#}', { filepath: './path/to/file.extension', extension: 'extension', title: 'file.extension', lang: 'c#' }],
['/path to/file.extension {1,2,4-6}', { filepath: '/path to/file.extension', extension: 'extension', title: 'file.extension', lines: '1,2,4-6' }],
['/path to/file.extension {1,2,4-6 c#}', { filepath: '/path to/file.extension', extension: 'extension', title: 'file.extension', lines: '1,2,4-6', lang: 'c#' }],
['/path.to/file.extension [title]', { filepath: '/path.to/file.extension', extension: 'extension', title: 'title' }],
['./path.to/file.extension#region {c#}', { filepath: './path.to/file.extension', extension: 'extension', title: 'file.extension', region: '#region', lang: 'c#' }],
['/path/to/file#region {1,2,4-6}', { filepath: '/path/to/file', title: 'file', region: '#region', lines: '1,2,4-6' }],
['./path/to/file#region {1,2,4-6 c#}', { filepath: './path/to/file', title: 'file', region: '#region', lines: '1,2,4-6', lang: 'c#' }],
['/path to/file {1,2,4-6 c#} [title]', { filepath: '/path to/file', title: 'title', lines: '1,2,4-6', lang: 'c#' }],
['./path to/file#region {1,2,4-6 c#} [title]', { filepath: './path to/file', title: 'title', region: '#region', lines: '1,2,4-6', lang: 'c#' }],
]
describe('node/markdown/plugins/snippet', () => {
describe('dedent', () => {
@ -57,4 +93,10 @@ describe('node/markdown/plugins/snippet', () => {
`)
})
})
test('rawPathToToken', () => {
rawPathTokenMap.forEach(([rawPath, token]) => {
expect(removeEmptyKeys(rawPathToToken(rawPath))).toEqual(token)
})
})
})

@ -0,0 +1,21 @@
<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M5.03628 7.87818C4.75336 5.83955 6.15592 3.95466 8.16899 3.66815L33.6838 0.0367403C35.6969 -0.24977 37.5581 1.1706 37.841 3.20923L42.9637 40.1218C43.2466 42.1604 41.8441 44.0453 39.831 44.3319L14.3162 47.9633C12.3031 48.2498 10.4419 46.8294 10.159 44.7908L5.03628 7.87818Z" fill="url(#paint0_linear_1287_1214)"/>
<path d="M6.85877 7.6188C6.71731 6.59948 7.41859 5.65703 8.42512 5.51378L33.9399 1.88237C34.9465 1.73911 35.8771 2.4493 36.0186 3.46861L41.1412 40.3812C41.2827 41.4005 40.5814 42.343 39.5749 42.4862L14.0601 46.1176C13.0535 46.2609 12.1229 45.5507 11.9814 44.5314L6.85877 7.6188Z" fill="white"/>
<path d="M33.1857 14.9195L25.8505 34.1576C25.6991 34.5547 25.1763 34.63 24.9177 34.2919L12.3343 17.8339C12.0526 17.4655 12.3217 16.9339 12.7806 16.9524L22.9053 17.3607C22.9698 17.3633 23.0344 17.3541 23.0956 17.3337L32.5088 14.1992C32.9431 14.0546 33.3503 14.4878 33.1857 14.9195Z" fill="url(#paint1_linear_1287_1214)"/>
<path d="M27.0251 12.5756L19.9352 15.0427C19.8187 15.0832 19.7444 15.1986 19.7546 15.3231L20.3916 23.063C20.4066 23.2453 20.5904 23.3628 20.7588 23.2977L22.7226 22.5392C22.9064 22.4682 23.1021 22.6138 23.0905 22.8128L22.9102 25.8903C22.8982 26.0974 23.1093 26.2436 23.295 26.1567L24.4948 25.5953C24.6808 25.5084 24.892 25.6549 24.8795 25.8624L24.5855 30.6979C24.5671 31.0004 24.9759 31.1067 25.1013 30.8321L25.185 30.6487L29.4298 17.8014C29.5008 17.5863 29.2968 17.3809 29.0847 17.454L27.0519 18.1547C26.8609 18.2205 26.6675 18.0586 26.6954 17.8561L27.3823 12.8739C27.4103 12.6712 27.2163 12.5091 27.0251 12.5756Z" fill="url(#paint2_linear_1287_1214)"/>
<defs>
<linearGradient id="paint0_linear_1287_1214" x1="6.48163" y1="1.9759" x2="39.05" y2="48.2064" gradientUnits="userSpaceOnUse">
<stop stop-color="#49C7FF"/>
<stop offset="1" stop-color="#BD36FF"/>
</linearGradient>
<linearGradient id="paint1_linear_1287_1214" x1="11.8848" y1="16.4266" x2="26.7246" y2="31.4177" gradientUnits="userSpaceOnUse">
<stop stop-color="#41D1FF"/>
<stop offset="1" stop-color="#BD34FE"/>
</linearGradient>
<linearGradient id="paint2_linear_1287_1214" x1="21.8138" y1="13.7046" x2="26.2464" y2="28.8069" gradientUnits="userSpaceOnUse">
<stop stop-color="#FFEA83"/>
<stop offset="0.0833333" stop-color="#FFDD35"/>
<stop offset="1" stop-color="#FFA800"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

@ -0,0 +1,41 @@
<svg width="160" height="192" viewBox="0 0 160 192" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_1288_1252)">
<path d="M0.12699 43.8989C-0.863275 37.1255 4.04575 30.863 11.0915 29.911L113.152 16.1221C120.197 15.1702 126.712 19.8893 127.702 26.6627L147.873 164.635C148.863 171.409 143.954 177.671 136.908 178.623L39.1006 191.837C29.7063 193.107 21.0203 186.814 19.7001 177.784L0.12699 43.8989Z" fill="url(#paint0_linear_1288_1252)"/>
<path d="M10.1376 30.5728C9.06487 22.8787 14.3827 15.7647 22.0152 14.6834L124.678 0.138664C132.31 -0.942678 139.367 4.41806 140.44 12.1122L159.862 151.427C160.935 159.121 155.617 166.235 147.985 167.317L45.3224 181.861C37.6899 182.943 30.6329 177.582 29.5602 169.888L10.1376 30.5728Z" fill="url(#paint1_linear_1288_1252)"/>
<path d="M19.0979 33.7417C18.3346 28.2753 22.1183 23.221 27.5489 22.4527L121.946 9.09852C127.376 8.33025 132.397 12.1389 133.161 17.6054L151.402 148.258C152.165 153.725 148.382 158.779 142.951 159.547L48.5544 172.901C43.1238 173.67 38.1027 169.861 37.3394 164.395L19.0979 33.7417Z" fill="white"/>
<path d="M118.649 103.244L56.8226 111.376C54.3836 111.697 52.6843 113.807 53.027 116.09L57.0613 142.955C57.4041 145.237 59.6591 146.827 62.0981 146.507L123.924 138.375C126.363 138.054 128.063 135.943 127.72 133.661L123.686 106.796C123.343 104.513 121.088 102.923 118.649 103.244Z" stroke="url(#paint2_linear_1288_1252)" stroke-width="4"/>
<path d="M64.6477 140.356L61.2921 117.143L68.5741 116.148L77.0898 123.687L83.1382 114.157L90.4202 113.163L93.7764 136.375L86.4939 137.37L84.5693 124.057L78.5209 133.587L70.0052 126.047L71.9298 139.36L64.6477 140.356ZM110.16 134.136L97.609 124.365L104.891 123.369L103.163 111.421L110.446 110.427L112.173 122.374L119.455 121.379L110.16 134.136Z" fill="url(#paint3_linear_1288_1252)"/>
<path d="M106.461 37.6734L85.0897 89.1815C84.6484 90.245 83.1468 90.4541 82.4101 89.555L46.5625 45.7851C45.76 44.8053 46.5412 43.3811 47.858 43.4233L76.9122 44.3556C77.0976 44.3617 77.2828 44.3363 77.459 44.2807L104.529 35.76C105.778 35.3669 106.94 36.518 106.461 37.6734Z" fill="url(#paint4_linear_1288_1252)"/>
<path d="M88.8117 31.4996L68.4122 38.2029C68.0769 38.313 67.8619 38.6223 67.8893 38.955L69.591 59.6271C69.6311 60.114 70.1569 60.4249 70.6418 60.2485L76.2932 58.1908C76.8221 57.9984 77.3816 58.3843 77.3448 58.9164L76.7769 67.1425C76.7388 67.6961 77.3423 68.0835 77.8772 67.8484L81.3316 66.3297C81.8672 66.0943 82.4715 66.4829 82.4319 67.0371L81.508 79.9629C81.4502 80.7715 82.6224 81.0495 82.987 80.3136L83.2305 79.8222L95.63 45.426C95.8377 44.85 95.2552 44.3043 94.6453 44.503L88.7963 46.4074C88.2468 46.5862 87.6946 46.1564 87.778 45.615L89.8327 32.2912C89.9162 31.7488 89.3612 31.3188 88.8117 31.4996Z" fill="url(#paint5_linear_1288_1252)"/>
</g>
<defs>
<linearGradient id="paint0_linear_1288_1252" x1="0.447599" y1="16.413" x2="148.448" y2="191.541" gradientUnits="userSpaceOnUse">
<stop stop-color="#508AB7"/>
<stop offset="1" stop-color="#2D1342"/>
</linearGradient>
<linearGradient id="paint1_linear_1288_1252" x1="11.1858" y1="19.1536" x2="158.875" y2="162.67" gradientUnits="userSpaceOnUse">
<stop stop-color="#49C7FF"/>
<stop offset="1" stop-color="#BD36FF"/>
</linearGradient>
<linearGradient id="paint2_linear_1288_1252" x1="56.6798" y1="114.377" x2="122.209" y2="145.088" gradientUnits="userSpaceOnUse">
<stop stop-color="#49C8FF"/>
<stop offset="1" stop-color="#BE35FF"/>
</linearGradient>
<linearGradient id="paint3_linear_1288_1252" x1="61.7655" y1="117.538" x2="121.328" y2="133.876" gradientUnits="userSpaceOnUse">
<stop stop-color="#4BC7FF"/>
<stop offset="1" stop-color="#B93DFF"/>
</linearGradient>
<linearGradient id="paint4_linear_1288_1252" x1="45.2957" y1="42.0327" x2="84.5852" y2="84.667" gradientUnits="userSpaceOnUse">
<stop stop-color="#41D1FF"/>
<stop offset="1" stop-color="#BD34FE"/>
</linearGradient>
<linearGradient id="paint5_linear_1288_1252" x1="73.8285" y1="34.5977" x2="85.1242" y2="75.2134" gradientUnits="userSpaceOnUse">
<stop stop-color="#FFEA83"/>
<stop offset="0.0833333" stop-color="#FFDD35"/>
<stop offset="1" stop-color="#FFA800"/>
</linearGradient>
<clipPath id="clip0_1288_1252">
<rect width="160" height="192" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 4.3 KiB

@ -1,5 +1,5 @@
import { createRequire } from 'module'
import { defineConfig } from 'vitepress'
import { defineConfig, type DefaultTheme } from 'vitepress'
const require = createRequire(import.meta.url)
const pkg = require('vitepress/package.json')
@ -12,6 +12,10 @@ export default defineConfig({
lastUpdated: true,
cleanUrls: true,
markdown: {
math: true
},
sitemap: {
hostname: 'https://vitepress.dev',
transformItems(items) {
@ -19,17 +23,16 @@ export default defineConfig({
}
},
/* prettier-ignore */
head: [
['meta', { name: 'theme-color', content: '#3c8772' }],
[
'script',
{
src: 'https://cdn.usefathom.com/script.js',
'data-site': 'AZBRSFGG',
'data-spa': 'auto',
defer: ''
}
]
['link', { rel: 'icon', type: 'image/svg+xml', href: '/vitepress-logo-mini.svg' }],
['link', { rel: 'icon', type: 'image/png', href: '/vitepress-logo-mini.png' }],
['meta', { name: 'theme-color', content: '#5f67ee' }],
['meta', { name: 'og:type', content: 'website' }],
['meta', { name: 'og:locale', content: 'en' }],
['meta', { name: 'og:site_name', content: 'VitePress' }],
['meta', { name: 'og:image', content: 'https://vitepress.dev/vitepress-og.jpg' }],
['script', { src: 'https://cdn.usefathom.com/script.js', 'data-site': 'AZBRSFGG', 'data-spa': 'auto', defer: '' }]
],
locales: {
root: {
@ -39,8 +42,8 @@ export default defineConfig({
themeConfig: {
nav: nav(),
sidebar: {
'/guide/': sidebarGuide(),
'/reference/': sidebarReference()
'/guide/': { base: '/guide/', items: sidebarGuide() },
'/reference/': { base: '/reference/', items: sidebarReference() }
}
}
},
@ -52,18 +55,23 @@ export default defineConfig({
themeConfig: {
nav: zhNav(),
sidebar: {
'/zh/guide/': zhSidebarGuide(),
'/zh/reference/': zhSidebarReference()
'/zh/guide/': { base: '/zh/guide/', items: zhSidebarGuide() },
'/zh/reference/': {
base: '/zh/reference/',
items: zhSidebarReference()
}
}
}
}
},
themeConfig: {
logo: { src: '/vitepress-logo-mini.svg', width: 24, height: 24 },
// nav: nav(),
// sidebar: {
// '/guide/': sidebarGuide(),
// '/reference/': sidebarReference()
// '/guide/': { base: '/guide/', items: sidebarGuide() },
// '/reference/': { base: '/reference/', items: sidebarReference() }
// },
editLink: {
@ -96,9 +104,13 @@ export default defineConfig({
}
})
function nav() {
function nav(): DefaultTheme.NavItem[] {
return [
{ text: 'Guide', link: '/guide/what-is-vitepress', activeMatch: '/guide/' },
{
text: 'Guide',
link: '/guide/what-is-vitepress',
activeMatch: '/guide/'
},
{
text: 'Reference',
link: '/reference/site-config',
@ -120,142 +132,79 @@ function nav() {
]
}
function sidebarGuide() {
/* prettier-ignore */
function sidebarGuide(): DefaultTheme.SidebarItem[] {
return [
{
text: 'Introduction',
collapsed: false,
items: [
{ text: 'What is VitePress?', link: '/guide/what-is-vitepress' },
{ text: 'Getting Started', link: '/guide/getting-started' },
{ text: 'Routing', link: '/guide/routing' },
{ text: 'Deploy', link: '/guide/deploy' }
{ text: 'What is VitePress?', link: 'what-is-vitepress' },
{ text: 'Getting Started', link: 'getting-started' },
{ text: 'Routing', link: 'routing' },
{ text: 'Deploy', link: 'deploy' }
]
},
{
text: 'Writing',
collapsed: false,
items: [
{ text: 'Markdown Extensions', link: '/guide/markdown' },
{ text: 'Asset Handling', link: '/guide/asset-handling' },
{ text: 'Frontmatter', link: '/guide/frontmatter' },
{ text: 'Using Vue in Markdown', link: '/guide/using-vue' },
{ text: 'Internationalization', link: '/guide/i18n' }
{ text: 'Markdown Extensions', link: 'markdown' },
{ text: 'Asset Handling', link: 'asset-handling' },
{ text: 'Frontmatter', link: 'frontmatter' },
{ text: 'Using Vue in Markdown', link: 'using-vue' },
{ text: 'Internationalization', link: 'i18n' }
]
},
{
text: 'Customization',
collapsed: false,
items: [
{ text: 'Using a Custom Theme', link: '/guide/custom-theme' },
{
text: 'Extending the Default Theme',
link: '/guide/extending-default-theme'
},
{ text: 'Build-Time Data Loading', link: '/guide/data-loading' },
{ text: 'SSR Compatibility', link: '/guide/ssr-compat' },
{ text: 'Connecting to a CMS', link: '/guide/cms' }
{ text: 'Using a Custom Theme', link: 'custom-theme' },
{ text: 'Extending the Default Theme', link: 'extending-default-theme' },
{ text: 'Build-Time Data Loading', link: 'data-loading' },
{ text: 'SSR Compatibility', link: 'ssr-compat' },
{ text: 'Connecting to a CMS', link: 'cms' }
]
},
{
text: 'Experimental',
collapsed: false,
items: [
{
text: 'MPA Mode',
link: '/guide/mpa-mode'
},
{
text: 'Sitemap Generation',
link: '/guide/sitemap-generation'
}
{ text: 'MPA Mode', link: 'mpa-mode' },
{ text: 'Sitemap Generation', link: 'sitemap-generation' }
]
},
// {
// text: 'Migrations',
// collapsed: false,
// items: [
// {
// text: 'Migration from VuePress',
// link: '/guide/migration-from-vuepress'
// },
// {
// text: 'Migration from VitePress 0.x',
// link: '/guide/migration-from-vitepress-0'
// }
// ]
// },
{
text: 'Config & API Reference',
link: '/reference/site-config'
}
{ text: 'Config & API Reference', base: '/reference/', link: 'site-config' }
]
}
function sidebarReference() {
function sidebarReference(): DefaultTheme.SidebarItem[] {
return [
{
text: 'Reference',
items: [
{ text: 'Site Config', link: '/reference/site-config' },
{ text: 'Frontmatter Config', link: '/reference/frontmatter-config' },
{ text: 'Runtime API', link: '/reference/runtime-api' },
{ text: 'CLI', link: '/reference/cli' },
{ text: 'Site Config', link: 'site-config' },
{ text: 'Frontmatter Config', link: 'frontmatter-config' },
{ text: 'Runtime API', link: 'runtime-api' },
{ text: 'CLI', link: 'cli' },
{
text: 'Default Theme',
base: '/zh/reference/default-theme-',
items: [
{
text: 'Overview',
link: '/reference/default-theme-config'
},
{
text: 'Nav',
link: '/reference/default-theme-nav'
},
{
text: 'Sidebar',
link: '/reference/default-theme-sidebar'
},
{
text: 'Home Page',
link: '/reference/default-theme-home-page'
},
{
text: 'Footer',
link: '/reference/default-theme-footer'
},
{
text: 'Layout',
link: '/reference/default-theme-layout'
},
{
text: 'Badge',
link: '/reference/default-theme-badge'
},
{
text: 'Team Page',
link: '/reference/default-theme-team-page'
},
{
text: 'Prev / Next Links',
link: '/reference/default-theme-prev-next-links'
},
{
text: 'Edit Link',
link: '/reference/default-theme-edit-link'
},
{
text: 'Last Updated Timestamp',
link: '/reference/default-theme-last-updated'
},
{
text: 'Search',
link: '/reference/default-theme-search'
},
{
text: 'Carbon Ads',
link: '/reference/default-theme-carbon-ads'
}
{ text: 'Overview', link: 'config' },
{ text: 'Nav', link: 'nav' },
{ text: 'Sidebar', link: 'sidebar' },
{ text: 'Home Page', link: 'home-page' },
{ text: 'Footer', link: 'footer' },
{ text: 'Layout', link: 'layout' },
{ text: 'Badge', link: 'badge' },
{ text: 'Team Page', link: 'team-page' },
{ text: 'Prev / Next Links', link: 'prev-next-links' },
{ text: 'Edit Link', link: 'edit-link' },
{ text: 'Last Updated Timestamp', link: 'last-updated' },
{ text: 'Search', link: 'search' },
{ text: 'Carbon Ads', link: 'carbon-ads' }
]
}
]
@ -263,68 +212,43 @@ function sidebarReference() {
]
}
function zhNav() {
return [
{
text: '指引',
link: '/zh/guide/what-is-vitepress',
activeMatch: '/zh/guide/'
},
{
text: '配置参考',
link: '/zh/reference/site-config',
activeMatch: '/zh/reference/'
},
{
text: pkg.version,
items: [
// { text: 'itemA', link: '/item-1' },
{
text: '更新日志',
link: 'https://github.com/vuejs/vitepress/blob/main/CHANGELOG.md'
},
{
text: '贡献',
link: 'https://github.com/vuejs/vitepress/blob/main/.github/contributing.md'
}
]
}
]
}
function zhSidebarGuide() {
function zhSidebarGuide(): DefaultTheme.SidebarItem[] {
return [
// 匹配不同路由,侧边导航有所变化,如果没有多页面需求,可以只写一个数组
// link 字段以 / 开头,该根目录为 /docs/ 目录
{
text: '介绍',
// 是否可收起
// 初始折叠状态 true 为折叠
collapsed: true,
items: [
{ text: '什么是 VitePress?', link: '/zh/guide/what-is-vitepress' },
{ text: '快速开始', link: '/zh/guide/getting-started' },
{ text: '路由', link: '/zh/guide/routing' },
{ text: '部署', link: '/zh/guide/deploy' }
{ text: '什么是 VitePress?', link: 'what-is-vitepress' },
{ text: '快速开始', link: 'getting-started' },
{ text: '路由', link: 'routing' },
{ text: '部署', link: 'deploy' }
]
},
{
text: '编写',
collapsed: true,
items: [
{ text: 'Markdown 基础语法', link: '/zh/guide/markdown-base' },
{ text: 'Markdown 扩展', link: '/zh/guide/markdown' },
{ text: '静态资源处理', link: '/zh/guide/asset-handling' },
{ text: 'Frontmatter', link: '/zh/guide/frontmatter' },
{ text: '在 Markdown 中 使用 Vue', link: '/zh/guide/using-vue' },
{ text: '国际化', link: '/zh/guide/i18n' }
{ text: 'Markdown 基础语法', link: 'markdown-base' },
{ text: 'Markdown 扩展', link: 'markdown' },
{ text: '静态资源处理', link: 'asset-handling' },
{ text: 'Frontmatter', link: 'frontmatter' },
{ text: '在 Markdown 中 使用 Vue', link: 'using-vue' },
{ text: '国际化', link: 'i18n' }
]
},
{
text: '自定义',
collapsed: true,
items: [
{ text: '使用自定义主题', link: '/zh/guide/custom-theme' },
{ text: '扩展默认主题', link: '/zh/guide/extending-default-theme' },
{ text: '构建时数据加载', link: '/zh/guide/data-loading' },
{ text: 'SSR 兼容性', link: '/zh/guide/ssr-compat' },
{ text: '连接到 CMS', link: '/zh/guide/cms' }
{ text: '使用自定义主题', link: 'custom-theme' },
{ text: '扩展默认主题', link: 'extending-default-theme' },
{ text: '构建时数据加载', link: 'data-loading' },
{ text: 'SSR 兼容性', link: 'ssr-compat' },
{ text: '连接到 CMS', link: 'cms' }
]
},
{
@ -333,58 +257,94 @@ function zhSidebarGuide() {
items: [
{
text: 'MPA Mode',
link: '/zh/guide/mpa-mode'
link: '/guide/mpa-mode'
},
{
text: 'Sitemap 生成器',
link: '/zh/guide/sitemap-generation'
link: '/guide/sitemap-generation'
}
]
},
// {
// text: '迁移',
// collapsed: false,
// items: [
// {
// text: '从 VuePress 迁移',
// link: '/guide/migration-from-vuepress',
// },
// {
// text: '从 VitePress 0.x 迁移',
// link: '/guide/migration-from-vitepress-0',
// },
// ],
// },
{
text: '配置 & API 参考',
link: '/zh/reference/site-config'
base: '/zh/reference/',
link: 'site-config'
}
]
}
function zhSidebarReference() {
function zhSidebarReference(): DefaultTheme.SidebarItem[] {
return [
{
text: '参考',
items: [
{ text: '站点配置', link: '/zh/reference/site-config' },
{ text: 'Frontmatter 配置', link: '/zh/reference/frontmatter-config' },
{ text: 'Runtime API', link: '/zh/reference/runtime-api' },
{ text: 'CLI', link: '/zh/reference/cli' },
{ text: '站点配置', link: 'site-config' },
{ text: 'Frontmatter 配置', link: 'frontmatter-config' },
{ text: 'Runtime API', link: 'runtime-api' },
{ text: 'CLI', link: 'cli' },
{
text: '默认主题',
// collapsed: true,
base: '/zh/reference/default-theme-',
items: [
{ text: '概览', link: '/zh/reference/default-theme-config' },
{ text: '导航栏', link: '/zh/reference/default-theme-nav' },
{ text: '侧边栏', link: '/zh/reference/default-theme-sidebar' },
{ text: '主页', link: '/zh/reference/default-theme-home-page' },
{ text: '页脚', link: '/zh/reference/default-theme-footer' },
{ text: '布局', link: '/zh/reference/default-theme-layout' },
{ text: '徽标', link: '/zh/reference/default-theme-badge' },
{ text: '团队', link: '/zh/reference/default-theme-team-page' },
{
text: '上(下)一篇',
link: '/zh/reference/default-theme-prev-next-links'
},
{ text: '编辑链接', link: '/zh/reference/default-theme-edit-link' },
{
text: '最近更新时间',
link: '/zh/reference/default-theme-last-updated'
},
{ text: '搜索', link: '/zh/reference/default-theme-search' },
{
text: 'Carbon Ads',
link: '/zh/reference/default-theme-carbon-ads'
}
{ text: '概览', link: 'config' },
{ text: '导航栏', link: 'nav' },
{ text: '侧边栏', link: 'sidebar' },
{ text: '主页', link: 'home-page' },
{ text: '页脚', link: 'footer' },
{ text: '布局', link: 'layout' },
{ text: '徽标', link: 'badge' },
{ text: '团队', link: 'team-page' },
{ text: '上(下)一篇', link: 'prev-next-links' },
{ text: '编辑链接', link: 'edit-link' },
{ text: '最近更新时间', link: 'last-updated' },
{ text: '搜索', link: 'search' },
{ text: 'Carbon Ads', link: 'carbon-ads' }
]
}
]
}
]
}
function zhNav(): DefaultTheme.NavItem[] {
return [
{
text: '指引',
link: '/zh/guide/what-is-vitepress',
activeMatch: '/guide/'
},
{
text: '配置参考',
link: '/zh/reference/site-config',
activeMatch: '/reference/'
},
{
text: pkg.version,
items: [
// { text: 'itemA', link: '/item-1' },
{
text: '更新日志',
link: 'https://github.com/vuejs/vitepress/blob/main/CHANGELOG.md'
},
{
text: '贡献',
link: 'https://github.com/vuejs/vitepress/blob/main/.github/contributing.md'
}
]
}
]
}

@ -0,0 +1,43 @@
<script setup>
import icon from './documate.vue'
</script>
<template>
<div class="ad-component">
<a target="_blank" href="https://github.com/aircodelabs/documate">
<icon class="icon"/>
<span>Embed AI chat in your VitePress using your own content. Open-source.</span>
<span class="cta">Try now </span>
</a>
</div>
</template>
<style scoped>
.ad-component {
margin-bottom: 2rem;
padding: .5rem .85rem;
border: 1px solid var(--vp-c-divider);
border-radius: 4px;
text-decoration: none;
color: var(--vp-c-text-2);
transition: color 0.4s ease-in-out;
font-size: 0.8rem;
}
.ad-component:hover {
color: var(--vp-c-text-1);
}
.ad-component .icon {
display: inline-block;
width: .75rem;
height: .75rem;
margin-right: 0.3rem;
}
.ad-component .cta {
margin-left: 0.3rem;
text-decoration: underline;
text-underline-offset: 2px;
}
</style>

@ -0,0 +1,5 @@
<template>
<svg viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M3.79938 23.5375C3.57959 23.516 3.36074 23.4856 3.14338 23.4465C2.98375 23.4179 2.83446 23.3477 2.71056 23.243C2.58666 23.1384 2.49252 23.0029 2.43762 22.8503C2.38272 22.6977 2.36899 22.5334 2.39782 22.3738C2.42665 22.2142 2.49702 22.065 2.60185 21.9412C3.10678 21.346 3.45159 20.6318 3.60369 19.8662C3.632 19.7246 3.57661 19.476 3.29108 19.1978C1.26031 17.2225 0 14.5431 0 11.5769C0 5.38615 5.44985 0.5 12 0.5C18.5502 0.5 24 5.38615 24 11.5769C24 17.7677 18.5502 22.6538 12 22.6538C10.9748 22.6538 9.97785 22.5345 9.02523 22.3105C7.46812 23.289 5.62931 23.7208 3.79938 23.5375ZM12.7957 18.2748C12.7504 18.3232 12.6907 18.3474 12.6165 18.3474C12.5423 18.3474 12.4805 18.3232 12.431 18.2748C12.3857 18.2305 12.3569 18.1721 12.3445 18.0995C12.258 17.4628 12.1632 16.9288 12.0602 16.4976C11.9571 16.0664 11.8212 15.7158 11.6522 15.4457C11.4832 15.1717 11.2587 14.9541 10.9784 14.7929C10.7023 14.6317 10.3459 14.5028 9.90907 14.4061C9.47225 14.3053 8.93448 14.2146 8.29574 14.134C8.21745 14.1259 8.15357 14.0977 8.10412 14.0494C8.05468 14.001 8.02995 13.9406 8.02995 13.868C8.02995 13.7955 8.05468 13.7351 8.10412 13.6867C8.15357 13.6383 8.21745 13.6101 8.29574 13.602C8.9386 13.5335 9.47844 13.4549 9.91525 13.3663C10.3521 13.2736 10.7106 13.1447 10.9908 12.9794C11.271 12.8142 11.4956 12.5925 11.6646 12.3145C11.8376 12.0364 11.9736 11.6798 12.0725 11.2445C12.1756 10.8093 12.2662 10.2713 12.3445 9.63052C12.3569 9.56201 12.3857 9.50559 12.431 9.46126C12.4805 9.4129 12.5423 9.38872 12.6165 9.38872C12.6907 9.38872 12.7504 9.4129 12.7957 9.46126C12.8452 9.50559 12.8761 9.56201 12.8885 9.63052C12.9709 10.2713 13.0615 10.8093 13.1604 11.2445C13.2635 11.6798 13.3994 12.0364 13.5684 12.3145C13.7374 12.5925 13.962 12.8142 14.2422 12.9794C14.5224 13.1447 14.8809 13.2736 15.3178 13.3663C15.7586 13.4549 16.2985 13.5335 16.9372 13.602C17.0155 13.6101 17.0773 13.6383 17.1226 13.6867C17.1721 13.7351 17.1968 13.7955 17.1968 13.868C17.1968 13.9406 17.1721 14.001 17.1226 14.0494C17.0773 14.0977 17.0155 14.1259 16.9372 14.134C16.2985 14.2025 15.7586 14.2831 15.3178 14.3758C14.8809 14.4645 14.5224 14.5914 14.2422 14.7567C13.962 14.9219 13.7374 15.1435 13.5684 15.4216C13.3994 15.6997 13.2635 16.0563 13.1604 16.4915C13.0615 16.9268 12.9709 17.4628 12.8885 18.0995C12.8761 18.1721 12.8452 18.2305 12.7957 18.2748ZM8.77789 11.9578C8.74492 11.9901 8.70371 12.0062 8.65425 12.0062C8.54711 12.0062 8.4853 11.9498 8.46882 11.8369C8.42349 11.4541 8.37404 11.1559 8.32047 10.9423C8.2669 10.7247 8.18448 10.5614 8.07322 10.4526C7.96195 10.3438 7.79094 10.2612 7.56017 10.2048C7.33351 10.1484 7.02239 10.0859 6.62679 10.0174C6.50316 10.0013 6.44135 9.94284 6.44135 9.84209C6.44135 9.74538 6.49492 9.68694 6.60206 9.66679C7.00591 9.59425 7.32115 9.52977 7.5478 9.47335C7.77857 9.4129 7.95164 9.33029 8.06703 9.2255C8.18242 9.1167 8.2669 8.95549 8.32047 8.74191C8.37404 8.52832 8.42349 8.23212 8.46882 7.8533C8.4853 7.74046 8.54711 7.68404 8.65425 7.68404C8.7614 7.68404 8.82116 7.73845 8.83352 7.84725C8.88708 8.23413 8.94066 8.53839 8.99423 8.76004C9.0478 8.97766 9.13022 9.14289 9.24149 9.25573C9.35686 9.36454 9.52788 9.44716 9.75454 9.50358C9.9853 9.55596 10.3026 9.61037 10.7065 9.66679C10.7518 9.67485 10.7889 9.695 10.8177 9.72724C10.8507 9.75545 10.8672 9.79373 10.8672 9.84209C10.8672 9.94284 10.8136 10.0013 10.7065 10.0174C10.3026 10.094 9.98736 10.1625 9.76072 10.2229C9.53406 10.2834 9.36305 10.368 9.24767 10.4768C9.13228 10.5816 9.0478 10.7408 8.99423 10.9544C8.94066 11.1639 8.88708 11.4601 8.83352 11.843C8.82939 11.8873 8.81085 11.9256 8.77789 11.9578ZM11.6213 7.98024C11.6048 8.05278 11.5636 8.08905 11.4977 8.08905C11.4235 8.08905 11.3823 8.05278 11.374 7.98024C11.3163 7.67799 11.2628 7.45635 11.2133 7.3153C11.168 7.17022 11.0712 7.06746 10.9228 7.007C10.7786 6.94655 10.5354 6.88812 10.1934 6.8317C10.1192 6.81558 10.0821 6.77528 10.0821 6.7108C10.0821 6.63826 10.1192 6.59796 10.1934 6.5899C10.5354 6.52945 10.7786 6.47102 10.9228 6.4146C11.0712 6.35415 11.168 6.2534 11.2133 6.11235C11.2628 5.96727 11.3163 5.74159 11.374 5.43531C11.3823 5.36277 11.4235 5.3265 11.4977 5.3265C11.5636 5.3265 11.6048 5.36277 11.6213 5.43531C11.6749 5.74159 11.7264 5.96727 11.7758 6.11235C11.8253 6.2534 11.9221 6.35415 12.0663 6.4146C12.2106 6.47102 12.4537 6.52945 12.7957 6.5899C12.8699 6.59796 12.907 6.63826 12.907 6.7108C12.907 6.77528 12.8699 6.81558 12.7957 6.8317C12.4537 6.88812 12.2106 6.94655 12.0663 7.007C11.9221 7.06746 11.8253 7.17022 11.7758 7.3153C11.7264 7.45635 11.6749 7.67799 11.6213 7.98024Z" />
</svg>
</template>

@ -0,0 +1,13 @@
// .vitepress/theme/index.js
import { h } from 'vue'
import DefaultTheme from 'vitepress/theme'
import AdComponent from './AdComponent.vue'
export default {
...DefaultTheme,
Layout() {
return h(DefaultTheme.Layout, null, {
'doc-before': () => h(AdComponent)
})
}
}

@ -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)
- <pathname:///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"}
<!-- there is no need to specify pathname:// if the target is explicitly specified -->
```
**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).

@ -13,7 +13,7 @@ A data loader file must end with either `.data.js` or `.data.ts`. The file shoul
export default {
load() {
return {
data: 'hello'
hello: 'world'
}
}
}
@ -35,7 +35,7 @@ Output:
```json
{
"data": "hello"
"hello": "world"
}
```
@ -99,7 +99,8 @@ The loaded data will be an array with the type of `ContentData[]`:
```ts
interface ContentData {
// mapped absolute URL for the page. e.g. /posts/hello.html
// mapped URL for the page. e.g. /posts/hello.html (does not include base)
// manually iterate or use custom `transform` to normalize the paths
url: string
// frontmatter data of the page
frontmatter: Record<string, any>

@ -111,7 +111,7 @@ Set up a new project and change these settings using your dashboard:
- **Build Command:** `npm run docs:build`
- **Output Directory:** `docs/.vitepress/dist`
- **Node Version:** `16` (or above, by default it usually will be 14 or 16, but on Cloudflare Pages the default is still 12, so you may need to [change that](https://developers.cloudflare.com/pages/platform/build-configuration/))
- **Node Version:** `18` (or above)
::: warning
Don't enable options like _Auto Minify_ for HTML code. It will remove comments from output which have meaning to Vue. You may see hydration mismatch errors if they get removed.
@ -157,6 +157,7 @@ Don't enable options like _Auto Minify_ for HTML code. It will remove comments f
with:
fetch-depth: 0 # Not needed if lastUpdated is not enabled
# - uses: pnpm/action-setup@v2 # Uncomment this if you're using pnpm
# - uses: oven-sh/setup-bun@v1 # Uncomment this if you're using Bun
- name: Setup Node
uses: actions/setup-node@v3
with:
@ -165,9 +166,11 @@ Don't enable options like _Auto Minify_ for HTML code. It will remove comments f
- name: Setup Pages
uses: actions/configure-pages@v3
- name: Install dependencies
run: npm ci # or pnpm install / yarn install
run: npm ci # or pnpm install / yarn install / bun install
- name: Build with VitePress
run: npm run docs:build # or pnpm docs:build / yarn docs:build
run: |
npm run docs:build # or pnpm docs:build / yarn docs:build / bun run docs:build
touch docs/.vitepress/dist/.nojekyll
- name: Upload artifact
uses: actions/upload-pages-artifact@v2
with:
@ -202,7 +205,7 @@ Don't enable options like _Auto Minify_ for HTML code. It will remove comments f
2. Create a file named `.gitlab-ci.yml` in the root of your project with the content below. This will build and deploy your site whenever you make changes to your content:
```yaml
image: node:16
image: node:18
pages:
cache:
paths:

@ -1,3 +1,7 @@
---
outline: deep
---
# Extending the Default Theme
VitePress' default theme is optimized for documentation, and can be customized. Consult the [Default Theme Config Overview](../reference/default-theme-config) for a comprehensive list of options.
@ -29,8 +33,8 @@ export default DefaultTheme
```css
/* .vitepress/theme/custom.css */
:root {
--vp-c-brand: #646cff;
--vp-c-brand-light: #747bff;
--vp-c-brand-1: #646cff;
--vp-c-brand-2: #747bff;
}
```
@ -94,6 +98,7 @@ export default {
// .vitepress/theme/index.js
import DefaultTheme from 'vitepress/theme'
/** @type {import('vitepress').Theme} */
export default {
extends: DefaultTheme,
enhanceApp(ctx) {
@ -103,6 +108,21 @@ export default {
}
```
If you're using TypeScript:
```ts
// .vitepress/theme/index.ts
import type { Theme } from 'vitepress'
import DefaultTheme from 'vitepress/theme'
export default {
extends: DefaultTheme,
async enhanceApp({ app }) {
// register your custom global components
ctx.app.component('MyGlobalComponent' /* ... */)
}
} satisfies Theme
```
Since we are using Vite, you can also leverage Vite's [glob import feature](https://vitejs.dev/guide/features.html#glob-import) to auto register a directory of components.
## Layout Slots
@ -195,6 +215,102 @@ Full list of slots available in the default theme layout:
- `nav-screen-content-before`
- `nav-screen-content-after`
## Using View Transitions API
### On Appearance Toggle
You can extend the default theme to provide a custom transition when the color mode is toggled. An example:
```vue
<!-- .vitepress/theme/Layout.vue -->
<script setup lang="ts">
import { useData } from 'vitepress'
import DefaultTheme from 'vitepress/theme'
import { nextTick, provide } from 'vue'
const { isDark } = useData()
const enableTransitions = () =>
'startViewTransition' in document &&
window.matchMedia('(prefers-reduced-motion: no-preference)').matches
provide('toggle-appearance', async ({ clientX: x, clientY: y }: MouseEvent) => {
if (!enableTransitions()) {
isDark.value = !isDark.value
return
}
const clipPath = [
`circle(0px at ${x}px ${y}px)`,
`circle(${Math.hypot(
Math.max(x, innerWidth - x),
Math.max(y, innerHeight - y)
)}px at ${x}px ${y}px)`
]
await document.startViewTransition(async () => {
isDark.value = !isDark.value
await nextTick()
}).ready
document.documentElement.animate(
{ clipPath: isDark.value ? clipPath.reverse() : clipPath },
{
duration: 300,
easing: 'ease-in',
pseudoElement: `::view-transition-${isDark.value ? 'old' : 'new'}(root)`
}
)
})
</script>
<template>
<DefaultTheme.Layout />
</template>
<style>
::view-transition-old(root),
::view-transition-new(root) {
animation: none;
mix-blend-mode: normal;
}
::view-transition-old(root),
.dark::view-transition-new(root) {
z-index: 1;
}
::view-transition-new(root),
.dark::view-transition-old(root) {
z-index: 9999;
}
.VPSwitchAppearance {
width: 22px !important;
}
.VPSwitchAppearance .check {
transform: none !important;
}
</style>
```
Result (**warning!**: flashing colors, sudden movements, bright lights):
<details>
<summary>Demo</summary>
![Appearance Toggle Transition Demo](/appearance-toggle-transition.webp)
</details>
Refer [Chrome Docs](https://developer.chrome.com/docs/web-platform/view-transitions/) from more details on view transitions.
### On Route Change
Coming soon.
## Overriding Internal Components
You can use Vite's [aliases](https://vitejs.dev/config/shared-options.html#resolve-alias) to replace default theme components with your custom ones:

@ -8,7 +8,7 @@ You can try VitePress directly in your browser on [StackBlitz](https://vitepress
### Prerequisites
- [Node.js](https://nodejs.org/) version 16 or higher.
- [Node.js](https://nodejs.org/) version 18 or higher.
- Terminal for accessing VitePress via its command line interface (CLI).
- Text Editor with [Markdown](https://en.wikipedia.org/wiki/Markdown) syntax support.
- [VSCode](https://code.visualstudio.com/) is recommended, along with the [official Vue extension](https://marketplace.visualstudio.com/items?itemName=Vue.volar).
@ -18,17 +18,21 @@ VitePress can be used on its own, or be installed into an existing project. In b
::: code-group
```sh [npm]
$ npm install -D vitepress
$ npm add -D vitepress
```
```sh [pnpm]
$ pnpm add -D vitepress@latest
$ pnpm add -D vitepress
```
```sh [yarn]
$ yarn add -D vitepress
```
```sh [bun]
$ bun add -D vitepress
```
:::
::: details Getting missing peer deps warnings?
@ -47,6 +51,12 @@ If using PNPM, you will notice a missing peer warning for `@docsearch/js`. This
:::
::: tip NOTE
VitePress is an ESM-only package. Don't use `require()` to import it, and make sure your nearest `package.json` contains `"type": "module"`, or change the file extension of your relevant files like `.vitepress/config.js` to `.mjs`/`.mts`. Refer to [Vite's troubleshooting guide](http://vitejs.dev/guide/troubleshooting.html#this-package-is-esm-only) for more details. Also, inside async CJS contexts, you can use `await import('vitepress')` instead.
:::
### Setup Wizard
VitePress ships with a command line setup wizard that will help you scaffold a basic project. After installation, start the wizard by running:
@ -61,13 +71,15 @@ $ npx vitepress init
$ pnpm dlx vitepress init
```
```sh [bun]
$ bunx vitepress init
```
:::
You will be greeted with a few simple questions:
<p>
<img src="./vitepress-init.png" alt="vitepress init screenshot" style="border-radius:8px">
</p>
<<< @/snippets/init.ansi
::: tip Vue as Peer Dependency
If you intend to perform customization that uses Vue components or APIs, you should also explicitly install `vue` as a peer dependency.
@ -155,6 +167,10 @@ $ pnpm run docs:dev
$ yarn docs:dev
```
```sh [bun]
$ bun run docs:dev
```
:::
Instead of npm scripts, you can also invoke VitePress directly with:
@ -169,6 +185,10 @@ $ npx vitepress dev docs
$ pnpm exec vitepress dev docs
```
```sh [bun]
$ bunx vitepress dev docs
```
:::
More command line usage is documented in the [CLI Reference](../reference/cli).

@ -206,6 +206,25 @@ console.log('Hello, VitePress!')
```
:::
Also, you may set custom titles globally by adding the following content in site config, helpful if not writing in English:
```ts
// config.ts
export default defineConfig({
// ...
markdown: {
container: {
tipLabel: '提示',
warningLabel: '警告',
dangerLabel: '危险',
infoLabel: '信息',
detailsLabel: '详细信息'
}
}
// ...
})
```
### `raw`
This is a special container that can be used to prevent style and router conflicts with VitePress. This is especially useful when you're documenting component libraries. You might also wanna check out [whyframe](https://whyframe.dev/docs/integrations/vitepress) for better isolation.
@ -220,32 +239,29 @@ Wraps in a <div class="vp-raw">
`vp-raw` class can be directly used on elements too. Style isolation is currently opt-in:
::: details
- Install required deps with your preferred package manager:
- Install `postcss` with your preferred package manager:
```sh
$ npm install -D postcss postcss-prefix-selector
$ npm add -D postcss
```
- Create a file named `docs/.postcssrc.cjs` and add this to it:
- Create a file named `docs/postcss.config.mjs` and add this to it:
```js
module.exports = {
plugins: {
'postcss-prefix-selector': {
prefix: ':not(:where(.vp-raw *))',
includeFiles: [/vp-doc\.css/],
transform(prefix, _selector) {
const [selector, pseudo = ''] = _selector.split(/(:\S*)$/)
return selector + prefix + pseudo
}
}
}
import { postcssIsolateStyles } from 'vitepress'
export default {
plugins: [postcssIsolateStyles()]
}
```
:::
It uses [`postcss-prefix-selector`](https://github.com/postcss/postcss-load-config) under the hood. You can pass its options like this:
```js
postcssIsolateStyles({
includeFiles: [/vp-doc\.css/] // defaults to /base\.css/
})
```
## Syntax Highlighting in Code Blocks
@ -507,6 +523,8 @@ Please see [`markdown` options](../reference/site-config#markdown) for more deta
You can add `:line-numbers` / `:no-line-numbers` mark in your fenced code blocks to override the value set in config.
You can also customize the starting line number by adding `=` after `:line-numbers`. For example, `:line-numbers=2` means the line numbers in code blocks will start from `2`.
**Input**
````md
@ -521,6 +539,12 @@ const line3 = 'This is line 3'
const line2 = 'This is line 2'
const line3 = 'This is line 3'
```
```ts:line-numbers=2 {1}
// line-numbers is enabled and start from 2
const line3 = 'This is line 3'
const line4 = 'This is line 4'
```
````
**Output**
@ -537,6 +561,12 @@ const line2 = 'This is line 2'
const line3 = 'This is line 3'
```
```ts:line-numbers=2 {1}
// line-numbers is enabled and start from 2
const line3 = 'This is line 3'
const line4 = 'This is line 4'
```
## Import Code Snippets
You can import code snippets from existing files via following syntax:
@ -563,7 +593,7 @@ It also supports [line highlighting](#line-highlighting-in-code-blocks):
**Output**
<<< @/snippets/snippet.js{2}
<<< @/snippets/snippet.js
::: tip
The value of `@` corresponds to the source root. By default it's the VitePress project root, unless `srcDir` is configured. Alternatively, you can also import from relative paths:
@ -778,19 +808,65 @@ The format of the selected line range can be: `{3,}`, `{,10}`, `{1,10}`
Note that this does not throw errors if your file is not present. Hence, when using this feature make sure that the contents are being rendered as expected.
:::
## Math Equations
This is currently opt-in. To enable it, you need to install `markdown-it-mathjax3` and set `markdown.math` to `true` in your config file:
```sh
npm add -D markdown-it-mathjax3
```
```ts
// .vitepress/config.ts
export default {
markdown: {
math: true
}
}
```
**Input**
```md
When $a \ne 0$, there are two solutions to $(ax^2 + bx + c = 0)$ and they are
$$ x = {-b \pm \sqrt{b^2-4ac} \over 2a} $$
**Maxwell's equations:**
| equation | description |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- |
| $\nabla \cdot \vec{\mathbf{B}} = 0$ | divergence of $\vec{\mathbf{B}}$ is zero |
| $\nabla \times \vec{\mathbf{E}}\, +\, \frac1c\, \frac{\partial\vec{\mathbf{B}}}{\partial t} = \vec{\mathbf{0}}$ | curl of $\vec{\mathbf{E}}$ is proportional to the rate of change of $\vec{\mathbf{B}}$ |
| $\nabla \times \vec{\mathbf{B}} -\, \frac1c\, \frac{\partial\vec{\mathbf{E}}}{\partial t} = \frac{4\pi}{c}\vec{\mathbf{j}} \nabla \cdot \vec{\mathbf{E}} = 4 \pi \rho$ | _wha?_ |
```
**Output**
When $a \ne 0$, there are two solutions to $(ax^2 + bx + c = 0)$ and they are
$$ x = {-b \pm \sqrt{b^2-4ac} \over 2a} $$
**Maxwell's equations:**
| equation | description |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- |
| $\nabla \cdot \vec{\mathbf{B}} = 0$ | divergence of $\vec{\mathbf{B}}$ is zero |
| $\nabla \times \vec{\mathbf{E}}\, +\, \frac1c\, \frac{\partial\vec{\mathbf{B}}}{\partial t} = \vec{\mathbf{0}}$ | curl of $\vec{\mathbf{E}}$ is proportional to the rate of change of $\vec{\mathbf{B}}$ |
| $\nabla \times \vec{\mathbf{B}} -\, \frac1c\, \frac{\partial\vec{\mathbf{E}}}{\partial t} = \frac{4\pi}{c}\vec{\mathbf{j}} \nabla \cdot \vec{\mathbf{E}} = 4 \pi \rho$ | _wha?_ |
## Advanced Configuration
VitePress uses [markdown-it](https://github.com/markdown-it/markdown-it) as the Markdown renderer. A lot of the extensions above are implemented via custom plugins. You can further customize the `markdown-it` instance using the `markdown` option in `.vitepress/config.js`:
```js
const anchor = require('markdown-it-anchor')
import markdownItAnchor from 'markdown-it-anchor'
import markdownItFoo from 'markdown-it-foo'
module.exports = {
markdown: {
// options for markdown-it-anchor
// https://github.com/valeriangalliat/markdown-it-anchor#usage
anchor: {
permalink: anchor.permalink.headerLink()
permalink: markdownItAnchor.permalink.headerLink()
},
// options for @mdit-vue/plugin-toc
@ -799,7 +875,7 @@ module.exports = {
config: (md) => {
// use more markdown-it plugins!
md.use(require('markdown-it-xxx'))
md.use(markdownItFoo)
}
}
}

@ -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
<a href="/pure.html" target="_self">Link to pure.html</a>
```
:::
## Generating Clean URL

@ -52,6 +52,7 @@ Since [`Theme.enhanceApp`](./custom-theme#theme-interface) can be async, you can
```js
// .vitepress/theme/index.js
/** @type {import('vitepress').Theme} */
export default {
// ...
async enhanceApp({ app }) {
@ -63,6 +64,22 @@ export default {
}
```
If you're using TypeScript:
```ts
// .vitepress/theme/index.ts
import type { Theme } from 'vitepress'
export default {
// ...
async enhanceApp({ app }) {
if (!import.meta.env.SSR) {
const plugin = await import('plugin-that-access-window-on-import')
app.use(plugin)
}
}
} satisfies Theme
```
### `defineClientComponent`
VitePress provides a convenience helper for importing Vue components that access browser APIs on import.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

@ -15,6 +15,9 @@ hero:
- theme: alt
text: View on GitHub
link: https://github.com/vuejs/vitepress
image:
src: /vitepress-logo-large.webp
alt: VitePress
features:
- icon: 📝
@ -30,3 +33,25 @@ features:
title: Ship Fast Sites
details: Fast initial load with static HTML, fast post-load navigation with client-side routing.
---
<style>
:root {
--vp-home-hero-name-color: transparent;
--vp-home-hero-name-background: -webkit-linear-gradient(120deg, #bd34fe 30%, #41d1ff);
--vp-home-hero-image-background-image: linear-gradient(-45deg, #bd34fe 50%, #47caff 50%);
--vp-home-hero-image-filter: blur(44px);
}
@media (min-width: 640px) {
:root {
--vp-home-hero-image-filter: blur(56px);
}
}
@media (min-width: 960px) {
:root {
--vp-home-hero-image-filter: blur(68px);
}
}
</style>

@ -3,11 +3,12 @@
"private": true,
"type": "module",
"scripts": {
"dev": "vitepress",
"dev": "vitepress dev",
"build": "vitepress build",
"preview": "vitepress preview"
},
"devDependencies": {
"markdown-it-mathjax3": "^4.3.2",
"vitepress": "workspace:*"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

@ -0,0 +1,21 @@
<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M5.03628 7.87818C4.75336 5.83955 6.15592 3.95466 8.16899 3.66815L33.6838 0.0367403C35.6969 -0.24977 37.5581 1.1706 37.841 3.20923L42.9637 40.1218C43.2466 42.1604 41.8441 44.0453 39.831 44.3319L14.3162 47.9633C12.3031 48.2498 10.4419 46.8294 10.159 44.7908L5.03628 7.87818Z" fill="url(#paint0_linear_1287_1214)"/>
<path d="M6.85877 7.6188C6.71731 6.59948 7.41859 5.65703 8.42512 5.51378L33.9399 1.88237C34.9465 1.73911 35.8771 2.4493 36.0186 3.46861L41.1412 40.3812C41.2827 41.4005 40.5814 42.343 39.5749 42.4862L14.0601 46.1176C13.0535 46.2609 12.1229 45.5507 11.9814 44.5314L6.85877 7.6188Z" fill="white"/>
<path d="M33.1857 14.9195L25.8505 34.1576C25.6991 34.5547 25.1763 34.63 24.9177 34.2919L12.3343 17.8339C12.0526 17.4655 12.3217 16.9339 12.7806 16.9524L22.9053 17.3607C22.9698 17.3633 23.0344 17.3541 23.0956 17.3337L32.5088 14.1992C32.9431 14.0546 33.3503 14.4878 33.1857 14.9195Z" fill="url(#paint1_linear_1287_1214)"/>
<path d="M27.0251 12.5756L19.9352 15.0427C19.8187 15.0832 19.7444 15.1986 19.7546 15.3231L20.3916 23.063C20.4066 23.2453 20.5904 23.3628 20.7588 23.2977L22.7226 22.5392C22.9064 22.4682 23.1021 22.6138 23.0905 22.8128L22.9102 25.8903C22.8982 26.0974 23.1093 26.2436 23.295 26.1567L24.4948 25.5953C24.6808 25.5084 24.892 25.6549 24.8795 25.8624L24.5855 30.6979C24.5671 31.0004 24.9759 31.1067 25.1013 30.8321L25.185 30.6487L29.4298 17.8014C29.5008 17.5863 29.2968 17.3809 29.0847 17.454L27.0519 18.1547C26.8609 18.2205 26.6675 18.0586 26.6954 17.8561L27.3823 12.8739C27.4103 12.6712 27.2163 12.5091 27.0251 12.5756Z" fill="url(#paint2_linear_1287_1214)"/>
<defs>
<linearGradient id="paint0_linear_1287_1214" x1="6.48163" y1="1.9759" x2="39.05" y2="48.2064" gradientUnits="userSpaceOnUse">
<stop stop-color="#49C7FF"/>
<stop offset="1" stop-color="#BD36FF"/>
</linearGradient>
<linearGradient id="paint1_linear_1287_1214" x1="11.8848" y1="16.4266" x2="26.7246" y2="31.4177" gradientUnits="userSpaceOnUse">
<stop stop-color="#41D1FF"/>
<stop offset="1" stop-color="#BD34FE"/>
</linearGradient>
<linearGradient id="paint2_linear_1287_1214" x1="21.8138" y1="13.7046" x2="26.2464" y2="28.8069" gradientUnits="userSpaceOnUse">
<stop stop-color="#FFEA83"/>
<stop offset="0.0833333" stop-color="#FFDD35"/>
<stop offset="1" stop-color="#FFA800"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 249 KiB

@ -32,39 +32,25 @@ Code above renders like:
## Customize Type Color
You can customize the `background-color` of badges by overriding css variables. The following are the default values:
You can customize the style of badges by overriding css variables. The following are the default values:
```css
:root {
--vp-badge-info-border: var(--vp-c-divider-light);
--vp-badge-info-border: transparent;
--vp-badge-info-text: var(--vp-c-text-2);
--vp-badge-info-bg: var(--vp-c-white-soft);
--vp-badge-info-bg: var(--vp-c-default-soft);
--vp-badge-tip-border: var(--vp-c-green-dimm-1);
--vp-badge-tip-text: var(--vp-c-green-darker);
--vp-badge-tip-bg: var(--vp-c-green-dimm-3);
--vp-badge-tip-border: transparent;
--vp-badge-tip-text: var(--vp-c-brand-1);
--vp-badge-tip-bg: var(--vp-c-brand-soft);
--vp-badge-warning-border: var(--vp-c-yellow-dimm-1);
--vp-badge-warning-text: var(--vp-c-yellow-darker);
--vp-badge-warning-bg: var(--vp-c-yellow-dimm-3);
--vp-badge-warning-border: transparent;
--vp-badge-warning-text: var(--vp-c-warning-1);
--vp-badge-warning-bg: var(--vp-c-warning-soft);
--vp-badge-danger-border: var(--vp-c-red-dimm-1);
--vp-badge-danger-text: var(--vp-c-red-darker);
--vp-badge-danger-bg: var(--vp-c-red-dimm-3);
}
.dark {
--vp-badge-info-border: var(--vp-c-divider-light);
--vp-badge-info-bg: var(--vp-c-black-mute);
--vp-badge-tip-border: var(--vp-c-green-dimm-2);
--vp-badge-tip-text: var(--vp-c-green-light);
--vp-badge-warning-border: var(--vp-c-yellow-dimm-2);
--vp-badge-warning-text: var(--vp-c-yellow-light);
--vp-badge-danger-border: var(--vp-c-red-dimm-2);
--vp-badge-danger-text: var(--vp-c-red-light);
--vp-badge-danger-border: transparent;
--vp-badge-danger-text: var(--vp-c-danger-1);
--vp-badge-danger-bg: var(--vp-c-danger-soft);
}
```

@ -66,7 +66,7 @@ export default {
The configuration for the nav menu item. More details in [Default Theme: Nav](./default-theme-nav#navigation-links).
```js
```ts
export default {
themeConfig: {
nav: [
@ -113,7 +113,7 @@ interface NavItemWithChildren {
The configuration for the sidebar menu item. More details in [Default Theme: Sidebar](./default-theme-sidebar).
```js
```ts
export default {
themeConfig: {
sidebar: [
@ -174,26 +174,33 @@ Setting this value to `false` prevents rendering of aside container.\
Setting this value to `true` renders the aside to the right.\
Setting this value to `left` renders the aside to the left.
## outline
If you want to disable it for all viewports, you should use `outline: false` instead.
- Type: `number | [number, number] | 'deep' | false`
- Default: `2`
- Can be overridden per page via [frontmatter](./frontmatter-config#outline)
The levels of header to display in the outline. You can specify a particular level by passing a number, or you can provide a level range by passing a tuple containing the bottom and upper limits. When passing `'deep'` which equals `[2, 6]`, all header levels are shown in the outline except `h1`. Set `false` to hide outline.
## outline
## outlineTitle
- Type: `Outline | Outline['level'] | false`
- Level can be overridden per page via [frontmatter](./frontmatter-config#outline)
- Type: `string`
- Default: `On this page`
Setting this value to `false` prevents rendering of outline container. Refer this interface for more details:
Can be used to customize the title of the right sidebar (on the top of outline links). This is useful when writing documentation in another language.
```ts
interface Outline {
/**
* The levels of headings to be displayed in the outline.
* Single number means only headings of that level will be displayed.
* If a tuple is passed, the first number is the minimum level and the second number is the maximum level.
* `'deep'` is same as `[2, 6]`, which means all headings from `<h2>` to `<h6>` will be displayed.
*
* @default 2
*/
level?: number | [number, number] | 'deep'
```js
export default {
themeConfig: {
outlineTitle: 'In hac pagina'
}
/**
* The title to be displayed on the outline.
*
* @default 'On this page'
*/
label?: string
}
```
@ -203,7 +210,7 @@ export default {
You may define this option to show your social account links with icons in nav.
```js
```ts
export default {
themeConfig: {
socialLinks: [
@ -275,7 +282,7 @@ export interface Footer {
Edit Link lets you display a link to edit the page on Git management services such as GitHub, or GitLab. See [Default Theme: Edit Link](./default-theme-edit-link) for more details.
```js
```ts
export default {
themeConfig: {
editLink: {
@ -324,7 +331,7 @@ export interface LastUpdatedOptions {
* @default
* { dateStyle: 'short', timeStyle: 'short' }
*/
formatOptions?: Intl.DateTimeFormatOptions
formatOptions?: Intl.DateTimeFormatOptions & { forceLocale?: boolean }
}
```
@ -374,7 +381,7 @@ Learn more in [Default Theme: Carbon Ads](./default-theme-carbon-ads)
Can be used to customize text appearing above previous and next links. Helpful if not writing docs in English. Also can be used to disable prev/next links globally. If you want to selectively enable/disable prev/next links, you can use [frontmatter](./default-theme-prev-next-links).
```js
```ts
export default {
themeConfig: {
docFooter: {

@ -74,7 +74,7 @@ interface HeroAction {
### Customizing the name color
VitePress uses the brand color (`--vp-c-brand`) for the `name`. However, you may customize this color by overriding `--vp-home-hero-name-color` variable.
VitePress uses the brand color (`--vp-c-brand-1`) for the `name`. However, you may customize this color by overriding `--vp-home-hero-name-color` variable.
```css
:root {

@ -24,4 +24,4 @@ lastUpdated: false
---
```
Also refer [Default Theme: Last Updated](./default-theme-last-updated#last-updated) for more details. Any truthy value at theme-level will also enable the feature unless explicitly disabled at site or page level.
Also refer [Default Theme: Last Updated](./default-theme-config#lastupdated) for more details. Any truthy value at theme-level will also enable the feature unless explicitly disabled at site or page level.

@ -36,3 +36,27 @@ Option `home` will generate templated "Homepage". In this layout, you can set ex
## No Layout
If you don't want any layout, you can pass `layout: false` through frontmatter. This option is helpful if you want a fully-customizable landing page (without any sidebar, navbar, or footer by default).
## Custom Layout
You can also use a custom layout:
```md
---
layout: foo
---
```
This will look for a component named `foo` registered in context. For example, you can register your component globally in `.vitepress/theme/index.ts`:
```ts
import DefaultTheme from 'vitepress/theme'
import Foo from './Foo.vue'
export default {
extends: DefaultTheme,
enhanceApp({ app }) {
app.component('foo', Foo)
}
}
```

@ -98,9 +98,9 @@ export default defineConfig({
Learn more in [MiniSearch docs](https://lucaong.github.io/minisearch/classes/_minisearch_.minisearch.html).
### Excluding pages from search
### Custom content renderer
You can exclude pages from search by adding `search: false` to the frontmatter of the page. Alternatively, you can also pass `exclude` function to `themeConfig.search.options` to exclude pages based on their path relative to `srcDir`:
You can customize the function used to render the markdown content before indexing it:
```ts
import { defineConfig } from 'vitepress'
@ -108,8 +108,68 @@ import { defineConfig } from 'vitepress'
export default defineConfig({
themeConfig: {
search: {
provider: 'local',
options: {
/**
* @param {string} src
* @param {import('vitepress').MarkdownEnv} env
* @param {import('markdown-it')} md
*/
_render(src, env, md) {
// return html string
}
}
}
}
})
```
This function will be stripped from client-side site data, so you can use Node.js APIs in it.
#### Example: Excluding pages from search
You can exclude pages from search by adding `search: false` to the frontmatter of the page. Alternatively:
```ts
import { defineConfig } from 'vitepress'
export default defineConfig({
themeConfig: {
search: {
provider: 'local',
options: {
exclude: (path) => path.startsWith('/some/path')
_render(src, env, md) {
const html = md.render(src, env)
if (env.frontmatter?.search === false) return ''
if (env.relativePath.startsWith('some/path')) return ''
return html
}
}
}
}
})
```
::: warning Note
In case a custom `_render` function is provided, you need to handle the `search: false` frontmatter yourself. Also, the `env` object won't be completely populated before `md.render` is called, so any checks on optional `env` properties like `frontmatter` should be done after that.
:::
#### Example: Transforming content - adding anchors
```ts
import { defineConfig } from 'vitepress'
export default defineConfig({
themeConfig: {
search: {
provider: 'local',
options: {
_render(src, env, md) {
const html = md.render(src, env)
if (env.frontmatter?.title)
return md.render(`# ${env.frontmatter.title}`) + html
return html
}
}
}
}

@ -159,14 +159,14 @@ aside: false
- Type: `number | [number, number] | 'deep' | false`
- Default: `2`
The levels of header in the outline to display for the page. It's same as [config.themeConfig.outline](./default-theme-config#outline), and it overrides the theme config.
The levels of header in the outline to display for the page. It's same as [config.themeConfig.outline.level](./default-theme-config#outline), and it overrides the value set in site-level config.
### lastUpdated
- Type: `boolean`
- Type: `boolean | Date`
- Default: `true`
Whether to display [last updated](./default-theme-last-updated) text in the footer of the current page.
Whether to display [last updated](./default-theme-last-updated) text in the footer of the current page. If a datetime is specified, it will be displayed instead of the last git modified timestamp.
```yaml
---

@ -10,7 +10,7 @@ Site config is where you can define the global settings of the site. App config
### Config Resolution
The config file is always resolved from `<root>/.vitepress/config.[ext]`, where `<root>` is your VitePress [project root](../guide/routing#root-and-source-directory), and `[ext]` is one of the supported file extensions. TypeScript is supported out of the box. Supported extensions include `.js`, `.ts`, `.cjs`, `.mjs`, `.cts`, and `.mts`.
The config file is always resolved from `<root>/.vitepress/config.[ext]`, where `<root>` is your VitePress [project root](../guide/routing#root-and-source-directory), and `[ext]` is one of the supported file extensions. TypeScript is supported out of the box. Supported extensions include `.js`, `.ts`, `.mjs`, and `.mts`.
It is recommended to use ES modules syntax in config files. The config file should default export an object:
@ -155,17 +155,56 @@ export default {
Additional elements to render in the `<head>` tag in the page HTML. The user-added tags are rendered before the closing `head` tag, after VitePress tags.
```ts
type HeadConfig =
| [string, Record<string, string>]
| [string, Record<string, string>, string]
```
#### Example: Adding a favicon
```ts
export default {
head: [['link', { rel: 'icon', href: '/favicon.ico' }]]
} // put favicon.ico in public directory, if base is set, use /base/favicon.ico
/* Would render:
<link rel="icon" href="/favicon.ico">
*/
```
#### Example: Adding Google Fonts
```ts
export default {
head: [
[
'link',
{ rel: 'preconnect', href: 'https://fonts.googleapis.com' }
],
[
'link',
{ rel: 'preconnect', href: 'https://fonts.gstatic.com', crossorigin: '' }
// would render:
//
// <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
],
[
'link',
{ href: 'https://fonts.googleapis.com/css2?family=Roboto&display=swap', rel: 'stylesheet' }
]
]
}
/* Would render:
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Roboto&display=swap" rel="stylesheet">
*/
```
#### Example: Registering a service worker
```ts
export default {
head: [
[
'script',
{ id: 'register-sw' },
@ -174,24 +213,50 @@ export default {
navigator.serviceWorker.register('/sw.js')
}
})()`
// would render:
//
// <script id="register-sw">
// ;(() => {
// if ('serviceWorker' in navigator) {
// navigator.serviceWorker.register('/sw.js')
// }
// })()
// </script>
]
]
}
/* Would render:
<script id="register-sw">
;(() => {
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js')
}
})()
</script>
*/
```
#### Example: Using Google Analytics
```ts
type HeadConfig =
| [string, Record<string, string>]
| [string, Record<string, string>, string]
export default {
head: [
[
'script',
{ async: '', src: 'https://www.googletagmanager.com/gtag/js?id=TAG_ID' }
],
[
'script',
{},
`window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'TAG_ID');`
]
]
}
/* Would render:
<script async src="https://www.googletagmanager.com/gtag/js?id=TAG_ID"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'TAG_ID');
</script>
*/
```
### lang
@ -239,7 +304,7 @@ Enabling this may require additional configuration on your hosting platform. For
- Type: `Record<string, string>`
Defines custom directory <-> URL mappings. See [Routing: Route Rewrites](../guide/routing#route-rewrites) for more details.
Defines custom directory &lt;-&gt; URL mappings. See [Routing: Route Rewrites](../guide/routing#route-rewrites) for more details.
```ts
export default {
@ -361,7 +426,7 @@ When set to `true`, the production app will be built in [MPA Mode](../guide/mpa-
### appearance
- Type: `boolean | 'dark'`
- Type: `boolean | 'dark' | 'force-dark' | import('@vueuse/core').UseDarkOptions`
- Default: `true`
Whether to enable dark mode (by adding the `.dark` class to the `<html>` element).
@ -372,6 +437,8 @@ Whether to enable dark mode (by adding the `.dark` class to the `<html>` element
This option injects an inline script that restores users settings from local storage using the `vitepress-theme-appearance` key. This ensures the `.dark` class is applied before the page is rendered to avoid flickering.
`appearance.initialValue` can only be `'dark' | undefined`. Refs or getters are not supported.
### lastUpdated
- Type: `boolean`
@ -391,18 +458,7 @@ Configure Markdown parser options. VitePress uses [Markdown-it](https://github.c
```js
export default {
markdown: {
theme: 'material-theme-palenight',
lineNumbers: true,
// adjust how header anchors are generated,
// useful for integrating with tools that use different conventions
anchor: {
slugify(str) {
return encodeURIComponent(str)
}
}
}
markdown: {...}
}
```
@ -458,8 +514,33 @@ interface MarkdownOptions extends MarkdownIt.Options {
// See: https://github.com/mdit-vue/mdit-vue/tree/main/packages/plugin-toc#options
toc?: TocPluginOptions
// @mdit-vue/plugin-component plugin options.
// See: https://github.com/mdit-vue/mdit-vue/tree/main/packages/plugin-component#options
component?: ComponentPluginOptions
// Configure the Markdown-it instance.
config?: (md: MarkdownIt) => void
// Same as `config` but will be applied before all other plugins.
preConfig?: (md: MarkdownIt) => void
// Disable cache (experimental)
cache?: boolean
// Math support (experimental)
// You need to install `markdown-it-mathjax3` and set `math` to `true` to enable it.
// You can also pass options to `markdown-it-mathjax3` here.
// See: https://github.com/tani/markdown-it-mathjax3#customization
math?: any
// Global custom container titles
container?: {
infoLabel?: string
tipLabel?: string
warningLabel?: string
dangerLabel?: string
detailsLabel?: string
}
}
```
@ -543,7 +624,7 @@ interface SSGContext {
`transformHead` is a build hook to transform the head before generating each page. It will allow you to add head entries that cannot be statically added to your VitePress config. You only need to return extra entries, they will be merged automatically with the existing ones.
::: warning
Don't mutate anything inside the `ctx`.
Don't mutate anything inside the `context`.
:::
```ts
@ -568,14 +649,34 @@ interface TransformContext {
}
```
Note that this hook is only called when generating the site statically. It is not called during dev. If you need to add dynamic head entries during dev, you can use the [`transformPageData`](#transformpagedata) hook instead:
```ts
export default {
transformPageData(pageData) {
pageData.frontmatter.head ??= []
pageData.frontmatter.head.push([
'meta',
{
name: 'og:title',
content:
pageData.frontmatter.layout === 'home'
? `VitePress`
: `${pageData.title} | VitePress`
}
])
}
}
```
### transformHtml
- Type: `(code: string, id: string, ctx: TransformContext) => Awaitable<string | void>`
- Type: `(code: string, id: string, context: TransformContext) => Awaitable<string | void>`
`transformHtml` is a build hook to transform the content of each page before saving to disk.
::: warning
Don't mutate anything inside the `ctx`. Also, modifying the html content may cause hydration problems in runtime.
Don't mutate anything inside the `context`. Also, modifying the html content may cause hydration problems in runtime.
:::
```ts
@ -588,12 +689,12 @@ export default {
### transformPageData
- Type: `(pageData: PageData, ctx: TransformPageContext) => Awaitable<Partial<PageData> | { [key: string]: any } | void>`
- Type: `(pageData: PageData, context: TransformPageContext) => Awaitable<Partial<PageData> | { [key: string]: any } | void>`
`transformPageData` is a hook to transform the `pageData` of each page. You can directly mutate `pageData` or return changed values which will be merged into PageData.
`transformPageData` is a hook to transform the `pageData` of each page. You can directly mutate `pageData` or return changed values which will be merged into the page data.
::: warning
Don't mutate anything inside the `ctx`.
Don't mutate anything inside the `context` and be careful that this might impact the performance of dev server, especially if you have some network requests or heavy computations (like generating images) in the hook. You can check for `process.env.NODE_ENV === 'production'` for conditional logic.
:::
```ts

@ -0,0 +1,16 @@
┌ Welcome to VitePress!
│
◇ Where should VitePress initialize the config?
│ ./docs
│
◇ Site title:
│ My Awesome Project
│
◇ Site description:
│ A VitePress Site
│
◆ Theme:
│ ● Default Theme (Out of the box, good-looking docs)
│ ○ Default Theme + Customization
│ ○ Custom Theme
└

@ -0,0 +1,906 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
"@algolia/autocomplete-core@1.9.3":
version "1.9.3"
resolved "https://registry.yarnpkg.com/@algolia/autocomplete-core/-/autocomplete-core-1.9.3.tgz#1d56482a768c33aae0868c8533049e02e8961be7"
integrity sha512-009HdfugtGCdC4JdXUbVJClA0q0zh24yyePn+KUGk3rP7j8FEe/m5Yo/z65gn6nP/cM39PxpzqKrL7A6fP6PPw==
dependencies:
"@algolia/autocomplete-plugin-algolia-insights" "1.9.3"
"@algolia/autocomplete-shared" "1.9.3"
"@algolia/autocomplete-plugin-algolia-insights@1.9.3":
version "1.9.3"
resolved "https://registry.yarnpkg.com/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.9.3.tgz#9b7f8641052c8ead6d66c1623d444cbe19dde587"
integrity sha512-a/yTUkcO/Vyy+JffmAnTWbr4/90cLzw+CC3bRbhnULr/EM0fGNvM13oQQ14f2moLMcVDyAx/leczLlAOovhSZg==
dependencies:
"@algolia/autocomplete-shared" "1.9.3"
"@algolia/autocomplete-preset-algolia@1.9.3":
version "1.9.3"
resolved "https://registry.yarnpkg.com/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.9.3.tgz#64cca4a4304cfcad2cf730e83067e0c1b2f485da"
integrity sha512-d4qlt6YmrLMYy95n5TB52wtNDr6EgAIPH81dvvvW8UmuWRgxEtY0NJiPwl/h95JtG2vmRM804M0DSwMCNZlzRA==
dependencies:
"@algolia/autocomplete-shared" "1.9.3"
"@algolia/autocomplete-shared@1.9.3":
version "1.9.3"
resolved "https://registry.yarnpkg.com/@algolia/autocomplete-shared/-/autocomplete-shared-1.9.3.tgz#2e22e830d36f0a9cf2c0ccd3c7f6d59435b77dfa"
integrity sha512-Wnm9E4Ye6Rl6sTTqjoymD+l8DjSTHsHboVRYrKgEt8Q7UHm9nYbqhN/i0fhUYA3OAEH7WA8x3jfpnmJm3rKvaQ==
"@algolia/cache-browser-local-storage@4.20.0":
version "4.20.0"
resolved "https://registry.yarnpkg.com/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.20.0.tgz#357318242fc542ffce41d6eb5b4a9b402921b0bb"
integrity sha512-uujahcBt4DxduBTvYdwO3sBfHuJvJokiC3BP1+O70fglmE1ShkH8lpXqZBac1rrU3FnNYSUs4pL9lBdTKeRPOQ==
dependencies:
"@algolia/cache-common" "4.20.0"
"@algolia/cache-common@4.20.0":
version "4.20.0"
resolved "https://registry.yarnpkg.com/@algolia/cache-common/-/cache-common-4.20.0.tgz#ec52230509fce891091ffd0d890618bcdc2fa20d"
integrity sha512-vCfxauaZutL3NImzB2G9LjLt36vKAckc6DhMp05An14kVo8F1Yofb6SIl6U3SaEz8pG2QOB9ptwM5c+zGevwIQ==
"@algolia/cache-in-memory@4.20.0":
version "4.20.0"
resolved "https://registry.yarnpkg.com/@algolia/cache-in-memory/-/cache-in-memory-4.20.0.tgz#5f18d057bd6b3b075022df085c4f83bcca4e3e67"
integrity sha512-Wm9ak/IaacAZXS4mB3+qF/KCoVSBV6aLgIGFEtQtJwjv64g4ePMapORGmCyulCFwfePaRAtcaTbMcJF+voc/bg==
dependencies:
"@algolia/cache-common" "4.20.0"
"@algolia/client-account@4.20.0":
version "4.20.0"
resolved "https://registry.yarnpkg.com/@algolia/client-account/-/client-account-4.20.0.tgz#23ce0b4cffd63100fb7c1aa1c67a4494de5bd645"
integrity sha512-GGToLQvrwo7am4zVkZTnKa72pheQeez/16sURDWm7Seyz+HUxKi3BM6fthVVPUEBhtJ0reyVtuK9ArmnaKl10Q==
dependencies:
"@algolia/client-common" "4.20.0"
"@algolia/client-search" "4.20.0"
"@algolia/transporter" "4.20.0"
"@algolia/client-analytics@4.20.0":
version "4.20.0"
resolved "https://registry.yarnpkg.com/@algolia/client-analytics/-/client-analytics-4.20.0.tgz#0aa6bef35d3a41ac3991b3f46fcd0bf00d276fa9"
integrity sha512-EIr+PdFMOallRdBTHHdKI3CstslgLORQG7844Mq84ib5oVFRVASuuPmG4bXBgiDbcsMLUeOC6zRVJhv1KWI0ug==
dependencies:
"@algolia/client-common" "4.20.0"
"@algolia/client-search" "4.20.0"
"@algolia/requester-common" "4.20.0"
"@algolia/transporter" "4.20.0"
"@algolia/client-common@4.20.0":
version "4.20.0"
resolved "https://registry.yarnpkg.com/@algolia/client-common/-/client-common-4.20.0.tgz#ca60f04466515548651c4371a742fbb8971790ef"
integrity sha512-P3WgMdEss915p+knMMSd/fwiHRHKvDu4DYRrCRaBrsfFw7EQHon+EbRSm4QisS9NYdxbS04kcvNoavVGthyfqQ==
dependencies:
"@algolia/requester-common" "4.20.0"
"@algolia/transporter" "4.20.0"
"@algolia/client-personalization@4.20.0":
version "4.20.0"
resolved "https://registry.yarnpkg.com/@algolia/client-personalization/-/client-personalization-4.20.0.tgz#ca81308e8ad0db3b27458b78355f124f29657181"
integrity sha512-N9+zx0tWOQsLc3K4PVRDV8GUeOLAY0i445En79Pr3zWB+m67V+n/8w4Kw1C5LlbHDDJcyhMMIlqezh6BEk7xAQ==
dependencies:
"@algolia/client-common" "4.20.0"
"@algolia/requester-common" "4.20.0"
"@algolia/transporter" "4.20.0"
"@algolia/client-search@4.20.0":
version "4.20.0"
resolved "https://registry.yarnpkg.com/@algolia/client-search/-/client-search-4.20.0.tgz#3bcce817ca6caedc835e0eaf6f580e02ee7c3e15"
integrity sha512-zgwqnMvhWLdpzKTpd3sGmMlr4c+iS7eyyLGiaO51zDZWGMkpgoNVmltkzdBwxOVXz0RsFMznIxB9zuarUv4TZg==
dependencies:
"@algolia/client-common" "4.20.0"
"@algolia/requester-common" "4.20.0"
"@algolia/transporter" "4.20.0"
"@algolia/logger-common@4.20.0":
version "4.20.0"
resolved "https://registry.yarnpkg.com/@algolia/logger-common/-/logger-common-4.20.0.tgz#f148ddf67e5d733a06213bebf7117cb8a651ab36"
integrity sha512-xouigCMB5WJYEwvoWW5XDv7Z9f0A8VoXJc3VKwlHJw/je+3p2RcDXfksLI4G4lIVncFUYMZx30tP/rsdlvvzHQ==
"@algolia/logger-console@4.20.0":
version "4.20.0"
resolved "https://registry.yarnpkg.com/@algolia/logger-console/-/logger-console-4.20.0.tgz#ac443d27c4e94357f3063e675039cef0aa2de0a7"
integrity sha512-THlIGG1g/FS63z0StQqDhT6bprUczBI8wnLT3JWvfAQDZX5P6fCg7dG+pIrUBpDIHGszgkqYEqECaKKsdNKOUA==
dependencies:
"@algolia/logger-common" "4.20.0"
"@algolia/requester-browser-xhr@4.20.0":
version "4.20.0"
resolved "https://registry.yarnpkg.com/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.20.0.tgz#db16d0bdef018b93b51681d3f1e134aca4f64814"
integrity sha512-HbzoSjcjuUmYOkcHECkVTwAelmvTlgs48N6Owt4FnTOQdwn0b8pdht9eMgishvk8+F8bal354nhx/xOoTfwiAw==
dependencies:
"@algolia/requester-common" "4.20.0"
"@algolia/requester-common@4.20.0":
version "4.20.0"
resolved "https://registry.yarnpkg.com/@algolia/requester-common/-/requester-common-4.20.0.tgz#65694b2263a8712b4360fef18680528ffd435b5c"
integrity sha512-9h6ye6RY/BkfmeJp7Z8gyyeMrmmWsMOCRBXQDs4mZKKsyVlfIVICpcSibbeYcuUdurLhIlrOUkH3rQEgZzonng==
"@algolia/requester-node-http@4.20.0":
version "4.20.0"
resolved "https://registry.yarnpkg.com/@algolia/requester-node-http/-/requester-node-http-4.20.0.tgz#b52b182b52b0b16dec4070832267d484a6b1d5bb"
integrity sha512-ocJ66L60ABSSTRFnCHIEZpNHv6qTxsBwJEPfYaSBsLQodm0F9ptvalFkHMpvj5DfE22oZrcrLbOYM2bdPJRHng==
dependencies:
"@algolia/requester-common" "4.20.0"
"@algolia/transporter@4.20.0":
version "4.20.0"
resolved "https://registry.yarnpkg.com/@algolia/transporter/-/transporter-4.20.0.tgz#7e5b24333d7cc9a926b2f6a249f87c2889b944a9"
integrity sha512-Lsii1pGWOAISbzeyuf+r/GPhvHMPHSPrTDWNcIzOE1SG1inlJHICaVe2ikuoRjcpgxZNU54Jl+if15SUCsaTUg==
dependencies:
"@algolia/cache-common" "4.20.0"
"@algolia/logger-common" "4.20.0"
"@algolia/requester-common" "4.20.0"
"@babel/parser@^7.23.0":
version "7.23.0"
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.23.0.tgz#da950e622420bf96ca0d0f2909cdddac3acd8719"
integrity sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==
"@docsearch/css@3.5.2", "@docsearch/css@^3.5.2":
version "3.5.2"
resolved "https://registry.yarnpkg.com/@docsearch/css/-/css-3.5.2.tgz#610f47b48814ca94041df969d9fcc47b91fc5aac"
integrity sha512-SPiDHaWKQZpwR2siD0KQUwlStvIAnEyK6tAE2h2Wuoq8ue9skzhlyVQ1ddzOxX6khULnAALDiR/isSF3bnuciA==
"@docsearch/js@^3.5.2":
version "3.5.2"
resolved "https://registry.yarnpkg.com/@docsearch/js/-/js-3.5.2.tgz#a11cb2e7e62890e9e940283fed6972ecf632629d"
integrity sha512-p1YFTCDflk8ieHgFJYfmyHBki1D61+U9idwrLh+GQQMrBSP3DLGKpy0XUJtPjAOPltcVbqsTjiPFfH7JImjUNg==
dependencies:
"@docsearch/react" "3.5.2"
preact "^10.0.0"
"@docsearch/react@3.5.2":
version "3.5.2"
resolved "https://registry.yarnpkg.com/@docsearch/react/-/react-3.5.2.tgz#2e6bbee00eb67333b64906352734da6aef1232b9"
integrity sha512-9Ahcrs5z2jq/DcAvYtvlqEBHImbm4YJI8M9y0x6Tqg598P40HTEkX7hsMcIuThI+hTFxRGZ9hll0Wygm2yEjng==
dependencies:
"@algolia/autocomplete-core" "1.9.3"
"@algolia/autocomplete-preset-algolia" "1.9.3"
"@docsearch/css" "3.5.2"
algoliasearch "^4.19.1"
"@esbuild/android-arm64@0.18.20":
version "0.18.20"
resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz#984b4f9c8d0377443cc2dfcef266d02244593622"
integrity sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==
"@esbuild/android-arm@0.18.20":
version "0.18.20"
resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.18.20.tgz#fedb265bc3a589c84cc11f810804f234947c3682"
integrity sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==
"@esbuild/android-x64@0.18.20":
version "0.18.20"
resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.18.20.tgz#35cf419c4cfc8babe8893d296cd990e9e9f756f2"
integrity sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==
"@esbuild/darwin-arm64@0.18.20":
version "0.18.20"
resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz#08172cbeccf95fbc383399a7f39cfbddaeb0d7c1"
integrity sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==
"@esbuild/darwin-x64@0.18.20":
version "0.18.20"
resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz#d70d5790d8bf475556b67d0f8b7c5bdff053d85d"
integrity sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==
"@esbuild/freebsd-arm64@0.18.20":
version "0.18.20"
resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz#98755cd12707f93f210e2494d6a4b51b96977f54"
integrity sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==
"@esbuild/freebsd-x64@0.18.20":
version "0.18.20"
resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz#c1eb2bff03915f87c29cece4c1a7fa1f423b066e"
integrity sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==
"@esbuild/linux-arm64@0.18.20":
version "0.18.20"
resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz#bad4238bd8f4fc25b5a021280c770ab5fc3a02a0"
integrity sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==
"@esbuild/linux-arm@0.18.20":
version "0.18.20"
resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz#3e617c61f33508a27150ee417543c8ab5acc73b0"
integrity sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==
"@esbuild/linux-ia32@0.18.20":
version "0.18.20"
resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz#699391cccba9aee6019b7f9892eb99219f1570a7"
integrity sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==
"@esbuild/linux-loong64@0.18.20":
version "0.18.20"
resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz#e6fccb7aac178dd2ffb9860465ac89d7f23b977d"
integrity sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==
"@esbuild/linux-mips64el@0.18.20":
version "0.18.20"
resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz#eeff3a937de9c2310de30622a957ad1bd9183231"
integrity sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==
"@esbuild/linux-ppc64@0.18.20":
version "0.18.20"
resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz#2f7156bde20b01527993e6881435ad79ba9599fb"
integrity sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==
"@esbuild/linux-riscv64@0.18.20":
version "0.18.20"
resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz#6628389f210123d8b4743045af8caa7d4ddfc7a6"
integrity sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==
"@esbuild/linux-s390x@0.18.20":
version "0.18.20"
resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz#255e81fb289b101026131858ab99fba63dcf0071"
integrity sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==
"@esbuild/linux-x64@0.18.20":
version "0.18.20"
resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz#c7690b3417af318a9b6f96df3031a8865176d338"
integrity sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==
"@esbuild/netbsd-x64@0.18.20":
version "0.18.20"
resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz#30e8cd8a3dded63975e2df2438ca109601ebe0d1"
integrity sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==
"@esbuild/openbsd-x64@0.18.20":
version "0.18.20"
resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz#7812af31b205055874c8082ea9cf9ab0da6217ae"
integrity sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==
"@esbuild/sunos-x64@0.18.20":
version "0.18.20"
resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz#d5c275c3b4e73c9b0ecd38d1ca62c020f887ab9d"
integrity sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==
"@esbuild/win32-arm64@0.18.20":
version "0.18.20"
resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz#73bc7f5a9f8a77805f357fab97f290d0e4820ac9"
integrity sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==
"@esbuild/win32-ia32@0.18.20":
version "0.18.20"
resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz#ec93cbf0ef1085cc12e71e0d661d20569ff42102"
integrity sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==
"@esbuild/win32-x64@0.18.20":
version "0.18.20"
resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz#786c5f41f043b07afb1af37683d7c33668858f6d"
integrity sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==
"@jridgewell/sourcemap-codec@^1.4.15":
version "1.4.15"
resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32"
integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==
"@types/linkify-it@*":
version "3.0.4"
resolved "https://registry.yarnpkg.com/@types/linkify-it/-/linkify-it-3.0.4.tgz#def6a9bb0ce78140860602f16ace37a9997f086a"
integrity sha512-hPpIeeHb/2UuCw06kSNAOVWgehBLXEo0/fUs0mw3W2qhqX89PI2yvok83MnuctYGCPrabGIoi0fFso4DQ+sNUQ==
"@types/markdown-it@^13.0.4":
version "13.0.5"
resolved "https://registry.yarnpkg.com/@types/markdown-it/-/markdown-it-13.0.5.tgz#b5bba2af9ee8473409fe1571ec036417cb1e98fa"
integrity sha512-QhJP7hkq3FCrFNx0szMNCT/79CXfcEgUIA3jc5GBfeXqoKsk3R8JZm2wRXJ2DiyjbPE4VMFOSDemLFcUTZmHEQ==
dependencies:
"@types/linkify-it" "*"
"@types/mdurl" "*"
"@types/mdurl@*":
version "1.0.4"
resolved "https://registry.yarnpkg.com/@types/mdurl/-/mdurl-1.0.4.tgz#574bfbec51eb41ab5f444116c8555bc4347feba5"
integrity sha512-ARVxjAEX5TARFRzpDRVC6cEk0hUIXCCwaMhz8y7S1/PxU6zZS1UMjyobz7q4w/D/R552r4++EhwmXK1N2rAy0A==
"@types/web-bluetooth@^0.0.18":
version "0.0.18"
resolved "https://registry.yarnpkg.com/@types/web-bluetooth/-/web-bluetooth-0.0.18.tgz#74bd1c8fd3a2058cb6fc76b188fcded50a83d866"
integrity sha512-v/ZHEj9xh82usl8LMR3GarzFY1IrbXJw5L4QfQhokjRV91q+SelFqxQWSep1ucXEZ22+dSTwLFkXeur25sPIbw==
"@vitejs/plugin-vue@4.3.1":
version "4.3.1"
resolved "https://registry.yarnpkg.com/@vitejs/plugin-vue/-/plugin-vue-4.3.1.tgz#635cf512dd1d5c78adf9e24615696e4918cd9d88"
integrity sha512-tUBEtWcF7wFtII7ayNiLNDTCE1X1afySEo+XNVMNkFXaThENyCowIEX095QqbJZGTgoOcSVDJGlnde2NG4jtbQ==
"@vue/compiler-core@3.3.6":
version "3.3.6"
resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.3.6.tgz#ffc14517e0a7269983b9a93994df9669e9e03506"
integrity sha512-2JNjemwaNwf+MkkatATVZi7oAH1Hx0B04DdPH3ZoZ8vKC1xZVP7nl4HIsk8XYd3r+/52sqqoz9TWzYc3yE9dqA==
dependencies:
"@babel/parser" "^7.23.0"
"@vue/shared" "3.3.6"
estree-walker "^2.0.2"
source-map-js "^1.0.2"
"@vue/compiler-dom@3.3.6":
version "3.3.6"
resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.3.6.tgz#683420cc201c3a48cb0841467bf19a433ffbede6"
integrity sha512-1MxXcJYMHiTPexjLAJUkNs/Tw2eDf2tY3a0rL+LfuWyiKN2s6jvSwywH3PWD8bKICjfebX3GWx2Os8jkRDq3Ng==
dependencies:
"@vue/compiler-core" "3.3.6"
"@vue/shared" "3.3.6"
"@vue/compiler-sfc@3.3.6":
version "3.3.6"
resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.3.6.tgz#00dce2e7aa569101009c5eedec4a69e2f831d8cc"
integrity sha512-/Kms6du2h1VrXFreuZmlvQej8B1zenBqIohP0690IUBkJjsFvJxY0crcvVRJ0UhMgSR9dewB+khdR1DfbpArJA==
dependencies:
"@babel/parser" "^7.23.0"
"@vue/compiler-core" "3.3.6"
"@vue/compiler-dom" "3.3.6"
"@vue/compiler-ssr" "3.3.6"
"@vue/reactivity-transform" "3.3.6"
"@vue/shared" "3.3.6"
estree-walker "^2.0.2"
magic-string "^0.30.5"
postcss "^8.4.31"
source-map-js "^1.0.2"
"@vue/compiler-ssr@3.3.6":
version "3.3.6"
resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.3.6.tgz#d767602563f2596a03b44b3dea4a32c715f64915"
integrity sha512-QTIHAfDCHhjXlYGkUg5KH7YwYtdUM1vcFl/FxFDlD6d0nXAmnjizka3HITp8DGudzHndv2PjKVS44vqqy0vP4w==
dependencies:
"@vue/compiler-dom" "3.3.6"
"@vue/shared" "3.3.6"
"@vue/devtools-api@^6.5.1":
version "6.5.1"
resolved "https://registry.yarnpkg.com/@vue/devtools-api/-/devtools-api-6.5.1.tgz#7f71f31e40973eeee65b9a64382b13593fdbd697"
integrity sha512-+KpckaAQyfbvshdDW5xQylLni1asvNSGme1JFs8I1+/H5pHEhqUKMEQD/qn3Nx5+/nycBq11qAEi8lk+LXI2dA==
"@vue/reactivity-transform@3.3.6":
version "3.3.6"
resolved "https://registry.yarnpkg.com/@vue/reactivity-transform/-/reactivity-transform-3.3.6.tgz#29d615455992d253b8f21b47d084445b5d3f916d"
integrity sha512-RlJl4dHfeO7EuzU1iJOsrlqWyJfHTkJbvYz/IOJWqu8dlCNWtxWX377WI0VsbAgBizjwD+3ZjdnvSyyFW1YVng==
dependencies:
"@babel/parser" "^7.23.0"
"@vue/compiler-core" "3.3.6"
"@vue/shared" "3.3.6"
estree-walker "^2.0.2"
magic-string "^0.30.5"
"@vue/reactivity@3.3.6":
version "3.3.6"
resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.3.6.tgz#436bd2997673ae2a7b6f4e1c376163f0445f9a5e"
integrity sha512-gtChAumfQz5lSy5jZXfyXbKrIYPf9XEOrIr6rxwVyeWVjFhJwmwPLtV6Yis+M9onzX++I5AVE9j+iPH60U+B8Q==
dependencies:
"@vue/shared" "3.3.6"
"@vue/runtime-core@3.3.6":
version "3.3.6"
resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.3.6.tgz#749ff325c95bb3a690c512da0215339fd241872c"
integrity sha512-qp7HTP1iw1UW2ZGJ8L3zpqlngrBKvLsDAcq5lA6JvEXHmpoEmjKju7ahM9W2p/h51h0OT5F2fGlP/gMhHOmbUA==
dependencies:
"@vue/reactivity" "3.3.6"
"@vue/shared" "3.3.6"
"@vue/runtime-dom@3.3.6":
version "3.3.6"
resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.3.6.tgz#30729eac969467c6be6723677d14b873918a467c"
integrity sha512-AoX3Cp8NqMXjLbIG9YR6n/pPLWE9TiDdk6wTJHFnl2GpHzDFH1HLBC9wlqqQ7RlnvN3bVLpzPGAAH00SAtOxHg==
dependencies:
"@vue/runtime-core" "3.3.6"
"@vue/shared" "3.3.6"
csstype "^3.1.2"
"@vue/server-renderer@3.3.6":
version "3.3.6"
resolved "https://registry.yarnpkg.com/@vue/server-renderer/-/server-renderer-3.3.6.tgz#b8a4d7254b67a5cc663f2b9e16cde019483620c9"
integrity sha512-kgLoN43W4ERdZ6dpyy+gnk2ZHtcOaIr5Uc/WUP5DRwutgvluzu2pudsZGoD2b7AEJHByUVMa9k6Sho5lLRCykw==
dependencies:
"@vue/compiler-ssr" "3.3.6"
"@vue/shared" "3.3.6"
"@vue/shared@3.3.6":
version "3.3.6"
resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.3.6.tgz#bd97c22972c6519250069297d01cbed077054b7e"
integrity sha512-Xno5pEqg8SVhomD0kTSmfh30ZEmV/+jZtyh39q6QflrjdJCXah5lrnOLi9KB6a5k5aAHXMXjoMnxlzUkCNfWLQ==
"@vueuse/core@10.5.0", "@vueuse/core@^10.5.0":
version "10.5.0"
resolved "https://registry.yarnpkg.com/@vueuse/core/-/core-10.5.0.tgz#04d1e6d26592bb997bb755a4830ea7583c3e8612"
integrity sha512-z/tI2eSvxwLRjOhDm0h/SXAjNm8N5ld6/SC/JQs6o6kpJ6Ya50LnEL8g5hoYu005i28L0zqB5L5yAl8Jl26K3A==
dependencies:
"@types/web-bluetooth" "^0.0.18"
"@vueuse/metadata" "10.5.0"
"@vueuse/shared" "10.5.0"
vue-demi ">=0.14.6"
"@vueuse/integrations@^10.5.0":
version "10.5.0"
resolved "https://registry.yarnpkg.com/@vueuse/integrations/-/integrations-10.5.0.tgz#38f00bd5a1cd0160645f0c75efd5d9579061e3d6"
integrity sha512-fm5sXLCK0Ww3rRnzqnCQRmfjDURaI4xMsx+T+cec0ngQqHx/JgUtm8G0vRjwtonIeTBsH1Q8L3SucE+7K7upJQ==
dependencies:
"@vueuse/core" "10.5.0"
"@vueuse/shared" "10.5.0"
vue-demi ">=0.14.6"
"@vueuse/metadata@10.5.0":
version "10.5.0"
resolved "https://registry.yarnpkg.com/@vueuse/metadata/-/metadata-10.5.0.tgz#7501a88cf5cbf7a515a03f0b8bbe3cecf30cad11"
integrity sha512-fEbElR+MaIYyCkeM0SzWkdoMtOpIwO72x8WsZHRE7IggiOlILttqttM69AS13nrDxosnDBYdyy3C5mR1LCxHsw==
"@vueuse/shared@10.5.0":
version "10.5.0"
resolved "https://registry.yarnpkg.com/@vueuse/shared/-/shared-10.5.0.tgz#b3ac8c190a5dae41db5e1b60fe304a9b4247393c"
integrity sha512-18iyxbbHYLst9MqU1X1QNdMHIjks6wC7XTVf0KNOv5es/Ms6gjVFCAAWTVP2JStuGqydg3DT+ExpFORUEi9yhg==
dependencies:
vue-demi ">=0.14.6"
algoliasearch@^4.19.1:
version "4.20.0"
resolved "https://registry.yarnpkg.com/algoliasearch/-/algoliasearch-4.20.0.tgz#700c2cb66e14f8a288460036c7b2a554d0d93cf4"
integrity sha512-y+UHEjnOItoNy0bYO+WWmLWBlPwDjKHW6mNHrPi0NkuhpQOOEbrkwQH/wgKFDLh7qlKjzoKeiRtlpewDPDG23g==
dependencies:
"@algolia/cache-browser-local-storage" "4.20.0"
"@algolia/cache-common" "4.20.0"
"@algolia/cache-in-memory" "4.20.0"
"@algolia/client-account" "4.20.0"
"@algolia/client-analytics" "4.20.0"
"@algolia/client-common" "4.20.0"
"@algolia/client-personalization" "4.20.0"
"@algolia/client-search" "4.20.0"
"@algolia/logger-common" "4.20.0"
"@algolia/logger-console" "4.20.0"
"@algolia/requester-browser-xhr" "4.20.0"
"@algolia/requester-common" "4.20.0"
"@algolia/requester-node-http" "4.20.0"
"@algolia/transporter" "4.20.0"
ansi-colors@^4.1.1:
version "4.1.3"
resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.3.tgz#37611340eb2243e70cc604cad35d63270d48781b"
integrity sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==
ansi-sequence-parser@^1.1.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/ansi-sequence-parser/-/ansi-sequence-parser-1.1.1.tgz#e0aa1cdcbc8f8bb0b5bca625aac41f5f056973cf"
integrity sha512-vJXt3yiaUL4UU546s3rPXlsry/RnM730G1+HkpKE012AN0sx1eOrxSu95oKDIonskeLTijMgqWZ3uDEe3NFvyg==
boolbase@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e"
integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==
cheerio-select@^1.5.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/cheerio-select/-/cheerio-select-1.6.0.tgz#489f36604112c722afa147dedd0d4609c09e1696"
integrity sha512-eq0GdBvxVFbqWgmCm7M3XGs1I8oLy/nExUnh6oLqmBditPO9AqQJrkslDpMun/hZ0yyTs8L0m85OHp4ho6Qm9g==
dependencies:
css-select "^4.3.0"
css-what "^6.0.1"
domelementtype "^2.2.0"
domhandler "^4.3.1"
domutils "^2.8.0"
cheerio@1.0.0-rc.10:
version "1.0.0-rc.10"
resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0-rc.10.tgz#2ba3dcdfcc26e7956fc1f440e61d51c643379f3e"
integrity sha512-g0J0q/O6mW8z5zxQ3A8E8J1hUgp4SMOvEoW/x84OwyHKe/Zccz83PVT4y5Crcr530FV6NgmKI1qvGTKVl9XXVw==
dependencies:
cheerio-select "^1.5.0"
dom-serializer "^1.3.2"
domhandler "^4.2.0"
htmlparser2 "^6.1.0"
parse5 "^6.0.1"
parse5-htmlparser2-tree-adapter "^6.0.1"
tslib "^2.2.0"
commander@9.2.0:
version "9.2.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-9.2.0.tgz#6e21014b2ed90d8b7c9647230d8b7a94a4a419a9"
integrity sha512-e2i4wANQiSXgnrBlIatyHtP1odfUp0BbV5Y5nEGbxtIrStkEOAAzCUirvLBNXHLr7kwLvJl6V+4V3XV9x7Wd9w==
commander@^6.1.0:
version "6.2.1"
resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c"
integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==
css-select@^4.3.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/css-select/-/css-select-4.3.0.tgz#db7129b2846662fd8628cfc496abb2b59e41529b"
integrity sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==
dependencies:
boolbase "^1.0.0"
css-what "^6.0.1"
domhandler "^4.3.1"
domutils "^2.8.0"
nth-check "^2.0.1"
css-what@^6.0.1:
version "6.1.0"
resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4"
integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==
csstype@^3.1.2:
version "3.1.2"
resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.2.tgz#1d4bf9d572f11c14031f0436e1c10bc1f571f50b"
integrity sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==
dom-serializer@^1.0.1, dom-serializer@^1.3.2:
version "1.4.1"
resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.4.1.tgz#de5d41b1aea290215dc45a6dae8adcf1d32e2d30"
integrity sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==
dependencies:
domelementtype "^2.0.1"
domhandler "^4.2.0"
entities "^2.0.0"
domelementtype@^2.0.1, domelementtype@^2.2.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d"
integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==
domhandler@^3.3.0:
version "3.3.0"
resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-3.3.0.tgz#6db7ea46e4617eb15cf875df68b2b8524ce0037a"
integrity sha512-J1C5rIANUbuYK+FuFL98650rihynUOEzRLxW+90bKZRWB6A1X1Tf82GxR1qAWLyfNPRvjqfip3Q5tdYlmAa9lA==
dependencies:
domelementtype "^2.0.1"
domhandler@^4.0.0, domhandler@^4.2.0, domhandler@^4.3.1:
version "4.3.1"
resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.3.1.tgz#8d792033416f59d68bc03a5aa7b018c1ca89279c"
integrity sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==
dependencies:
domelementtype "^2.2.0"
domutils@^2.4.2, domutils@^2.5.2, domutils@^2.8.0:
version "2.8.0"
resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135"
integrity sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==
dependencies:
dom-serializer "^1.0.1"
domelementtype "^2.2.0"
domhandler "^4.2.0"
entities@^2.0.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55"
integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==
esbuild@^0.18.10:
version "0.18.20"
resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.18.20.tgz#4709f5a34801b43b799ab7d6d82f7284a9b7a7a6"
integrity sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==
optionalDependencies:
"@esbuild/android-arm" "0.18.20"
"@esbuild/android-arm64" "0.18.20"
"@esbuild/android-x64" "0.18.20"
"@esbuild/darwin-arm64" "0.18.20"
"@esbuild/darwin-x64" "0.18.20"
"@esbuild/freebsd-arm64" "0.18.20"
"@esbuild/freebsd-x64" "0.18.20"
"@esbuild/linux-arm" "0.18.20"
"@esbuild/linux-arm64" "0.18.20"
"@esbuild/linux-ia32" "0.18.20"
"@esbuild/linux-loong64" "0.18.20"
"@esbuild/linux-mips64el" "0.18.20"
"@esbuild/linux-ppc64" "0.18.20"
"@esbuild/linux-riscv64" "0.18.20"
"@esbuild/linux-s390x" "0.18.20"
"@esbuild/linux-x64" "0.18.20"
"@esbuild/netbsd-x64" "0.18.20"
"@esbuild/openbsd-x64" "0.18.20"
"@esbuild/sunos-x64" "0.18.20"
"@esbuild/win32-arm64" "0.18.20"
"@esbuild/win32-ia32" "0.18.20"
"@esbuild/win32-x64" "0.18.20"
escape-goat@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/escape-goat/-/escape-goat-3.0.0.tgz#e8b5fb658553fe8a3c4959c316c6ebb8c842b19c"
integrity sha512-w3PwNZJwRxlp47QGzhuEBldEqVHHhh8/tIPcl6ecf2Bou99cdAt0knihBV0Ecc7CGxYduXVBDheH1K2oADRlvw==
esm@^3.2.25:
version "3.2.25"
resolved "https://registry.yarnpkg.com/esm/-/esm-3.2.25.tgz#342c18c29d56157688ba5ce31f8431fbb795cc10"
integrity sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==
estree-walker@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac"
integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==
focus-trap@^7.5.4:
version "7.5.4"
resolved "https://registry.yarnpkg.com/focus-trap/-/focus-trap-7.5.4.tgz#6c4e342fe1dae6add9c2aa332a6e7a0bbd495ba2"
integrity sha512-N7kHdlgsO/v+iD/dMoJKtsSqs5Dz/dXZVebRgJw23LDk+jMi/974zyiOYDziY2JPp8xivq9BmUGwIJMiuSBi7w==
dependencies:
tabbable "^6.2.0"
fsevents@~2.3.2:
version "2.3.3"
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6"
integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==
htmlparser2@^5.0.0:
version "5.0.1"
resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-5.0.1.tgz#7daa6fc3e35d6107ac95a4fc08781f091664f6e7"
integrity sha512-vKZZra6CSe9qsJzh0BjBGXo8dvzNsq/oGvsjfRdOrrryfeD9UOBEEQdeoqCRmKZchF5h2zOBMQ6YuQ0uRUmdbQ==
dependencies:
domelementtype "^2.0.1"
domhandler "^3.3.0"
domutils "^2.4.2"
entities "^2.0.0"
htmlparser2@^6.1.0:
version "6.1.0"
resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-6.1.0.tgz#c4d762b6c3371a05dbe65e94ae43a9f845fb8fb7"
integrity sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==
dependencies:
domelementtype "^2.0.1"
domhandler "^4.0.0"
domutils "^2.5.2"
entities "^2.0.0"
jsonc-parser@^3.2.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.2.0.tgz#31ff3f4c2b9793f89c67212627c51c6394f88e76"
integrity sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==
juice@^8.0.0:
version "8.1.0"
resolved "https://registry.yarnpkg.com/juice/-/juice-8.1.0.tgz#4ea23362522fe06418229943237ee3751a4fca70"
integrity sha512-FLzurJrx5Iv1e7CfBSZH68dC04EEvXvvVvPYB7Vx1WAuhCp1ZPIMtqxc+WTWxVkpTIC2Ach/GAv0rQbtGf6YMA==
dependencies:
cheerio "1.0.0-rc.10"
commander "^6.1.0"
mensch "^0.3.4"
slick "^1.12.2"
web-resource-inliner "^6.0.1"
magic-string@^0.30.5:
version "0.30.5"
resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.5.tgz#1994d980bd1c8835dc6e78db7cbd4ae4f24746f9"
integrity sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==
dependencies:
"@jridgewell/sourcemap-codec" "^1.4.15"
mark.js@8.11.1:
version "8.11.1"
resolved "https://registry.yarnpkg.com/mark.js/-/mark.js-8.11.1.tgz#180f1f9ebef8b0e638e4166ad52db879beb2ffc5"
integrity sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==
markdown-it-mathjax3@^4.3.2:
version "4.3.2"
resolved "https://registry.yarnpkg.com/markdown-it-mathjax3/-/markdown-it-mathjax3-4.3.2.tgz#1e34aa86f8560b283fd283008334adc2d6b05a37"
integrity sha512-TX3GW5NjmupgFtMJGRauioMbbkGsOXAAt1DZ/rzzYmTHqzkO1rNAdiMD4NiruurToPApn2kYy76x02QN26qr2w==
dependencies:
juice "^8.0.0"
mathjax-full "^3.2.0"
mathjax-full@^3.2.0:
version "3.2.2"
resolved "https://registry.yarnpkg.com/mathjax-full/-/mathjax-full-3.2.2.tgz#43f02e55219db393030985d2b6537ceae82f1fa7"
integrity sha512-+LfG9Fik+OuI8SLwsiR02IVdjcnRCy5MufYLi0C3TdMT56L/pjB0alMVGgoWJF8pN9Rc7FESycZB9BMNWIid5w==
dependencies:
esm "^3.2.25"
mhchemparser "^4.1.0"
mj-context-menu "^0.6.1"
speech-rule-engine "^4.0.6"
mensch@^0.3.4:
version "0.3.4"
resolved "https://registry.yarnpkg.com/mensch/-/mensch-0.3.4.tgz#770f91b46cb16ea5b204ee735768c3f0c491fecd"
integrity sha512-IAeFvcOnV9V0Yk+bFhYR07O3yNina9ANIN5MoXBKYJ/RLYPurd2d0yw14MDhpr9/momp0WofT1bPUh3hkzdi/g==
mhchemparser@^4.1.0:
version "4.2.1"
resolved "https://registry.yarnpkg.com/mhchemparser/-/mhchemparser-4.2.1.tgz#d73982e66bc06170a85b1985600ee9dabe157cb0"
integrity sha512-kYmyrCirqJf3zZ9t/0wGgRZ4/ZJw//VwaRVGA75C4nhE60vtnIzhl9J9ndkX/h6hxSN7pjg/cE0VxbnNM+bnDQ==
mime@^2.4.6:
version "2.6.0"
resolved "https://registry.yarnpkg.com/mime/-/mime-2.6.0.tgz#a2a682a95cd4d0cb1d6257e28f83da7e35800367"
integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==
minisearch@^6.1.0:
version "6.1.0"
resolved "https://registry.yarnpkg.com/minisearch/-/minisearch-6.1.0.tgz#6e74e743dbd0e88fa5ca52fef2391e0aa7055252"
integrity sha512-PNxA/X8pWk+TiqPbsoIYH0GQ5Di7m6326/lwU/S4mlo4wGQddIcf/V//1f9TB0V4j59b57b+HZxt8h3iMROGvg==
mj-context-menu@^0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/mj-context-menu/-/mj-context-menu-0.6.1.tgz#a043c5282bf7e1cf3821de07b13525ca6f85aa69"
integrity sha512-7NO5s6n10TIV96d4g2uDpG7ZDpIhMh0QNfGdJw/W47JswFcosz457wqz/b5sAKvl12sxINGFCn80NZHKwxQEXA==
nanoid@^3.3.6:
version "3.3.6"
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.6.tgz#443380c856d6e9f9824267d960b4236ad583ea4c"
integrity sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==
node-fetch@^2.6.0:
version "2.7.0"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d"
integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==
dependencies:
whatwg-url "^5.0.0"
nth-check@^2.0.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.1.1.tgz#c9eab428effce36cd6b92c924bdb000ef1f1ed1d"
integrity sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==
dependencies:
boolbase "^1.0.0"
parse5-htmlparser2-tree-adapter@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz#2cdf9ad823321140370d4dbf5d3e92c7c8ddc6e6"
integrity sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==
dependencies:
parse5 "^6.0.1"
parse5@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b"
integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==
picocolors@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c"
integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==
postcss@^8.4.27, postcss@^8.4.31:
version "8.4.31"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.31.tgz#92b451050a9f914da6755af352bdc0192508656d"
integrity sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==
dependencies:
nanoid "^3.3.6"
picocolors "^1.0.0"
source-map-js "^1.0.2"
preact@^10.0.0:
version "10.18.1"
resolved "https://registry.yarnpkg.com/preact/-/preact-10.18.1.tgz#3b84bb305f0b05f4ad5784b981d15fcec4e105da"
integrity sha512-mKUD7RRkQQM6s7Rkmi7IFkoEHjuFqRQUaXamO61E6Nn7vqF/bo7EZCmSyrUnp2UWHw0O7XjZ2eeXis+m7tf4lg==
rollup@^3.27.1:
version "3.29.4"
resolved "https://registry.yarnpkg.com/rollup/-/rollup-3.29.4.tgz#4d70c0f9834146df8705bfb69a9a19c9e1109981"
integrity sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==
optionalDependencies:
fsevents "~2.3.2"
shiki@^0.14.5:
version "0.14.5"
resolved "https://registry.yarnpkg.com/shiki/-/shiki-0.14.5.tgz#375dd214e57eccb04f0daf35a32aa615861deb93"
integrity sha512-1gCAYOcmCFONmErGTrS1fjzJLA7MGZmKzrBNX7apqSwhyITJg2O102uFzXUeBxNnEkDA9vHIKLyeKq0V083vIw==
dependencies:
ansi-sequence-parser "^1.1.0"
jsonc-parser "^3.2.0"
vscode-oniguruma "^1.7.0"
vscode-textmate "^8.0.0"
slick@^1.12.2:
version "1.12.2"
resolved "https://registry.yarnpkg.com/slick/-/slick-1.12.2.tgz#bd048ddb74de7d1ca6915faa4a57570b3550c2d7"
integrity sha512-4qdtOGcBjral6YIBCWJ0ljFSKNLz9KkhbWtuGvUyRowl1kxfuE1x/Z/aJcaiilpb3do9bl5K7/1h9XC5wWpY/A==
source-map-js@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c"
integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==
speech-rule-engine@^4.0.6:
version "4.0.7"
resolved "https://registry.yarnpkg.com/speech-rule-engine/-/speech-rule-engine-4.0.7.tgz#b655dacbad3dae04acc0f7665e26ef258397dd09"
integrity sha512-sJrL3/wHzNwJRLBdf6CjJWIlxC04iYKkyXvYSVsWVOiC2DSkHmxsqOhEeMsBA9XK+CHuNcsdkbFDnoUfAsmp9g==
dependencies:
commander "9.2.0"
wicked-good-xpath "1.3.0"
xmldom-sre "0.1.31"
tabbable@^6.2.0:
version "6.2.0"
resolved "https://registry.yarnpkg.com/tabbable/-/tabbable-6.2.0.tgz#732fb62bc0175cfcec257330be187dcfba1f3b97"
integrity sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==
tr46@~0.0.3:
version "0.0.3"
resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==
tslib@^2.2.0:
version "2.6.2"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae"
integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==
valid-data-url@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/valid-data-url/-/valid-data-url-3.0.1.tgz#826c1744e71b5632e847dd15dbd45b9fb38aa34f"
integrity sha512-jOWVmzVceKlVVdwjNSenT4PbGghU0SBIizAev8ofZVgivk/TVHXSbNL8LP6M3spZvkR9/QolkyJavGSX5Cs0UA==
vite@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/vite/-/vite-4.5.0.tgz#ec406295b4167ac3bc23e26f9c8ff559287cff26"
integrity sha512-ulr8rNLA6rkyFAlVWw2q5YJ91v098AFQ2R0PRFwPzREXOUJQPtFUG0t+/ZikhaOCDqFoDhN6/v8Sq0o4araFAw==
dependencies:
esbuild "^0.18.10"
postcss "^8.4.27"
rollup "^3.27.1"
optionalDependencies:
fsevents "~2.3.2"
"vitepress@workspace:*":
version "1.0.0-rc.24"
resolved "https://registry.yarnpkg.com/vitepress/-/vitepress-1.0.0-rc.24.tgz#517b44d10e0cd3773f5e2f9799c2bde8e60f0505"
integrity sha512-RpnL8cnOGwiRlBbrYQUm9sYkJbtyOt/wYXk2diTcokY4yvks/5lq9LuSt+MURWB6ZqwpSNHvTmxgaSfLoG0/OA==
dependencies:
"@docsearch/css" "^3.5.2"
"@docsearch/js" "^3.5.2"
"@types/markdown-it" "^13.0.4"
"@vitejs/plugin-vue" "4.3.1"
"@vue/devtools-api" "^6.5.1"
"@vueuse/core" "^10.5.0"
"@vueuse/integrations" "^10.5.0"
focus-trap "^7.5.4"
mark.js "8.11.1"
minisearch "^6.1.0"
shiki "^0.14.5"
vite "^4.5.0"
vue "^3.3.6"
vscode-oniguruma@^1.7.0:
version "1.7.0"
resolved "https://registry.yarnpkg.com/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz#439bfad8fe71abd7798338d1cd3dc53a8beea94b"
integrity sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==
vscode-textmate@^8.0.0:
version "8.0.0"
resolved "https://registry.yarnpkg.com/vscode-textmate/-/vscode-textmate-8.0.0.tgz#2c7a3b1163ef0441097e0b5d6389cd5504b59e5d"
integrity sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==
vue-demi@>=0.14.6:
version "0.14.6"
resolved "https://registry.yarnpkg.com/vue-demi/-/vue-demi-0.14.6.tgz#dc706582851dc1cdc17a0054f4fec2eb6df74c92"
integrity sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==
vue@^3.3.6:
version "3.3.6"
resolved "https://registry.yarnpkg.com/vue/-/vue-3.3.6.tgz#bc1b129a73705db16da90aa1edde539d7401ca9d"
integrity sha512-jJIDETeWJnoY+gfn4ZtMPMS5KtbP4ax+CT4dcQFhTnWEk8xMupFyQ0JxL28nvT/M4+p4a0ptxaV2WY0LiIxvRg==
dependencies:
"@vue/compiler-dom" "3.3.6"
"@vue/compiler-sfc" "3.3.6"
"@vue/runtime-dom" "3.3.6"
"@vue/server-renderer" "3.3.6"
"@vue/shared" "3.3.6"
web-resource-inliner@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/web-resource-inliner/-/web-resource-inliner-6.0.1.tgz#df0822f0a12028805fe80719ed52ab6526886e02"
integrity sha512-kfqDxt5dTB1JhqsCUQVFDj0rmY+4HLwGQIsLPbyrsN9y9WV/1oFDSx3BQ4GfCv9X+jVeQ7rouTqwK53rA/7t8A==
dependencies:
ansi-colors "^4.1.1"
escape-goat "^3.0.0"
htmlparser2 "^5.0.0"
mime "^2.4.6"
node-fetch "^2.6.0"
valid-data-url "^3.0.0"
webidl-conversions@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871"
integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==
whatwg-url@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d"
integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==
dependencies:
tr46 "~0.0.3"
webidl-conversions "^3.0.0"
wicked-good-xpath@1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/wicked-good-xpath/-/wicked-good-xpath-1.3.0.tgz#81b0e95e8650e49c94b22298fff8686b5553cf6c"
integrity sha512-Gd9+TUn5nXdwj/hFsPVx5cuHHiF5Bwuc30jZ4+ronF1qHK5O7HD0sgmXWSEgwKquT3ClLoKPVbO6qGwVwLzvAw==
xmldom-sre@0.1.31:
version "0.1.31"
resolved "https://registry.yarnpkg.com/xmldom-sre/-/xmldom-sre-0.1.31.tgz#10860d5bab2c603144597d04bf2c4980e98067f4"
integrity sha512-f9s+fUkX04BxQf+7mMWAp5zk61pciie+fFLC9hX9UVvCeJQfNHRHXpeo5MPcR0EUf57PYLdt+ZO4f3Ipk2oZUw==

@ -26,7 +26,7 @@
请注意,你应使用根绝对路径来引用放置在 `public` 中的文件 - 例如,`public/icon.png` 应始终在源代码中作为 `/icon.png` 引用。
但有一个例外:如果你在 `public` 中有一个 HTML 页面,并从主站点链接到它,路由默认会产生 404 错误。为了解决这个问题VitePress 提供了 `pathname//` 协议,它允许你像链接外部页面一样链接到同一域名的另一个页面。比较这两个链接:
<!-- 但有一个例外:如果你在 `public` 中有一个 HTML 页面,并从主站点链接到它,路由默认会产生 404 错误。为了解决这个问题VitePress 提供了 `pathname//` 协议,它允许你像链接外部页面一样链接到同一域名的另一个页面。比较这两个链接:
- [/pure.html](/pure.html)
- <pathname:///VitePressCN/pure.html>
@ -39,14 +39,14 @@
[Link to pure.html](/pure.html){target="\_self"}
[Link to pure.html](/pure.html){target="\_blank"}
<!-- 如果明确指定 target ,则无需指定 pathname:// -->
如果明确指定 target ,则无需指定 pathname://
```
**输出**
[链接到 pure.html](/pure.html){target="\_self"}
<br>
[链接到 pure.html](/pure.html){target="\_blank"}
[链接到 pure.html](/pure.html){target="\_blank"} -->
## 根 URL {#base-url}

@ -13,7 +13,7 @@ VitePress 提供了一个叫做**数据加载器**的功能,它允许你加载
export default {
load() {
return {
data: 'hello',
hello: 'world',
}
},
}
@ -35,7 +35,7 @@ import { data } from './example.data.js'
```json
{
"data": "hello"
"hello": "world"
}
```
@ -99,7 +99,8 @@ export default createContentLoader('posts/*.md' /* options */)
```ts
interface ContentData {
// mapped absolute URL for the page. e.g. /posts/hello.html
// mapped URL for the page. e.g. /posts/hello.html (does not include base)
// manually iterate or use custom `transform` to normalize the paths
url: string
// frontmatter data of the page
frontmatter: Record<string, any>

@ -111,7 +111,7 @@ Cache-Control: max-age=31536000,immutable
- **构建命令:** `npm run docs:build`
- **输出目录:** `docs/.vitepress/dist`
- **node 版本:** `16` (或更高版本,默认情况下通常为 14 或 16但在 Cloudflare 页面上,默认值仍然是 12因此你可能需要[更改该版本](https://developers.cloudflare.com/pages/platform/build-configuration/))
- **node 版本:** `18` (或更高版本)
::: warning 警告
不要为 HTML 代码启用 _Auto Minify_ 等选项。它将从输出中删除对 Vue 有意义的注释。如果被删除,你可能会看到 [hydration(HTML 添加交互的过程)](https://blog.csdn.net/qq_41800366/article/details/117738916) mismatch 错误。
@ -148,30 +148,33 @@ concurrency:
cancel-in-progress: false
jobs:
# Build job
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0 # Not needed if lastUpdated is not enabled
# - uses: pnpm/action-setup@v2 # Uncomment this if you're using pnpm
- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: 18
cache: npm # or pnpm / yarn
- name: Setup Pages
uses: actions/configure-pages@v3
- name: Install dependencies
run: npm ci # or pnpm install / yarn install
- name: Build with VitePress
run: npm run docs:build # or pnpm docs:build / yarn docs:build
- name: Upload artifact
uses: actions/upload-pages-artifact@v2
with:
path: docs/.vitepress/dist
# Build job
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0 # Not needed if lastUpdated is not enabled
# - uses: pnpm/action-setup@v2 # Uncomment this if you're using pnpm
# - uses: oven-sh/setup-bun@v1 # Uncomment this if you're using Bun
- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: 18
cache: npm # or pnpm / yarn
- name: Setup Pages
uses: actions/configure-pages@v3
- name: Install dependencies
run: npm ci # or pnpm install / yarn install / bun install
- name: Build with VitePress
run: |
npm run docs:build # or pnpm docs:build / yarn docs:build / bun run docs:build
touch docs/.vitepress/dist/.nojekyll
- name: Upload artifact
uses: actions/upload-pages-artifact@v2
with:
path: docs/.vitepress/dist
# Deployment job
deploy:
@ -202,7 +205,7 @@ jobs:
2. 在项目的根目录中创建一个名为 `.gitlab-ci.yml` 的文件,其中包含以下内容。每当您更改内容时,都会自动构建和部署您的网站:
```yaml
image: node:16
image: node:18
pages:
cache:
paths:

@ -1,3 +1,7 @@
---
outline: deep
---
# 扩展默认主题 {#extending-the-default-theme}
VitePress 默认的主题已经针对文档进行了优化,并且可以进行定制。请参考 [默认主题配置概览](../reference/default-theme-config) 获取完整的选项列表。
@ -29,8 +33,8 @@ export default DefaultTheme
```css
/* .vitepress/theme/custom.css */
:root {
--vp-c-brand: #646cff;
--vp-c-brand-light: #747bff;
--vp-c-brand-1: #646cff;
--vp-c-brand-2: #747bff;
}
```
@ -67,24 +71,24 @@ export default DefaultTheme
```js
// .vitepress/config.js
export default {
transformHead({ assets }) {
// adjust the regex accordingly to match your font
const myFontFile = assets.find(file => /font-name\.\w+\.woff2/)
if (myFontFile) {
return [
[
'link',
{
rel: 'preload',
href: myFontFile,
as: 'font',
type: 'font/woff2',
crossorigin: ''
}
]
]
}
}
transformHead({ assets }) {
// adjust the regex accordingly to match your font
const myFontFile = assets.find((file) => /font-name\.\w+\.woff2/)
if (myFontFile) {
return [
[
'link',
{
rel: 'preload',
href: myFontFile,
as: 'font',
type: 'font/woff2',
crossorigin: '',
},
],
]
}
},
}
```
@ -94,15 +98,32 @@ export default {
// .vitepress/theme/index.js
import DefaultTheme from 'vitepress/theme'
/** @type {import('vitepress').Theme} */
export default {
extends: DefaultTheme,
enhanceApp(ctx) {
// register your custom global components
ctx.app.component('MyGlobalComponent' /* ... */)
}
extends: DefaultTheme,
enhanceApp(ctx) {
// register your custom global components
ctx.app.component('MyGlobalComponent' /* ... */)
},
}
```
如果你使用 TypeScript:
```ts
// .vitepress/theme/index.ts
import type { Theme } from 'vitepress'
import DefaultTheme from 'vitepress/theme'
export default {
extends: DefaultTheme,
async enhanceApp({ app }) {
// register your custom global components
ctx.app.component('MyGlobalComponent' /* ... */)
},
} satisfies Theme
```
因为我们使用 Vite你还可以利用 Vite 的 [glob 导入功能](https://cn.vitejs.dev/guide/features.html#glob-import)来自动注册一个组件目录。
## 布局插槽 {#layout-slots}
@ -115,10 +136,10 @@ import DefaultTheme from 'vitepress/theme'
import MyLayout from './MyLayout.vue'
export default {
...DefaultTheme,
// override the Layout with a wrapper component that
// injects the slots
Layout: MyLayout
...DefaultTheme,
// override the Layout with a wrapper component that
// injects the slots
Layout: MyLayout,
}
```
@ -131,11 +152,9 @@ const { Layout } = DefaultTheme
</script>
<template>
<Layout>
<template #aside-outline-before>
My custom sidebar top content
</template>
</Layout>
<Layout>
<template #aside-outline-before> My custom sidebar top content </template>
</Layout>
</template>
```
@ -148,12 +167,12 @@ import DefaultTheme from 'vitepress/theme'
import MyComponent from './MyComponent.vue'
export default {
...DefaultTheme,
Layout() {
return h(DefaultTheme.Layout, null, {
'aside-outline-before': () => h(MyComponent)
})
}
...DefaultTheme,
Layout() {
return h(DefaultTheme.Layout, null, {
'aside-outline-before': () => h(MyComponent),
})
},
}
```
@ -199,18 +218,16 @@ import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vitepress'
export default defineConfig({
vite: {
resolve: {
alias: [
{
find: /^.*\/VPNavBar\.vue$/,
replacement: fileURLToPath(
new URL('./components/CustomNavBar.vue', import.meta.url)
)
}
]
}
}
vite: {
resolve: {
alias: [
{
find: /^.*\/VPNavBar\.vue$/,
replacement: fileURLToPath(new URL('./components/CustomNavBar.vue', import.meta.url)),
},
],
},
},
})
```

@ -8,7 +8,7 @@
### 前置知识 {#prerequisites}
- [Node.js](https://nodejs.org/) 16 及以上版本。
- [Node.js](https://nodejs.org/) 18 及以上版本。
- 通过命令行界面 (CLI) 访问 VitePress 的终端。
- 支持 [Markdown](https://en.wikipedia.org/wiki/Markdown) 语法的编辑器。
- 推荐 [VSCode](https://code.visualstudio.com/) 及其[官方 Vue 扩展](https://marketplace.visualstudio.com/items?itemName=Vue.volar)。
@ -18,17 +18,21 @@ VitePress 可以单独使用,也可以安装到现有项目中。在这两种
::: code-group
```sh [npm]
$ npm install -D vitepress
$ npm add -D vitepress
```
```sh [pnpm]
$ pnpm add -D vitepress@latest
$ pnpm add -D vitepress
```
```sh [yarn]
$ yarn add -D vitepress
```
```sh [bun]
$ bun add -D vitepress
```
:::
::: details 遇到了 missing peer deps 警告?
@ -47,6 +51,11 @@ $ yarn add -D vitepress
:::
::: tip 注意
VitePress 是仅 ESM 的软件包。不要使用 `require()` 导入它,并确保最新的 `package.json` 包含 `"type": "module"`,或者更改相关文件的文件扩展名,例如`.vitepress/config.js` 到 `.mjs`/`.mts`。更多详情请参考[Vite 故障排除指南](http://vitejs.dev/guide/troubleshooting.html#this-package-is-esm-only)。此外,在异步 CJS 上下文中,您可以使用 `await import('vitepress')` 代替。
:::
### 安装向导 {#setup-wizard}
VitePress 附带一个命令行设置向导,可以帮助你构建一个基本项目。安装后,通过运行以下命令启动向导:
@ -65,9 +74,7 @@ $ pnpm dlx vitepress init
你将需要回答几个简单的问题:
<p>
<img src="./vitepress-init.png" alt="vitepress init screenshot" style="border-radius:8px">
</p>
<<< @/snippets/init.ansi
::: tip Vue as Peer Dependency
如果打算使用 Vue 组件或 API 进行自定义,还应该明确地将 `vue` 安装为 peer dependency。

@ -0,0 +1,21 @@
<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M5.03628 7.87818C4.75336 5.83955 6.15592 3.95466 8.16899 3.66815L33.6838 0.0367403C35.6969 -0.24977 37.5581 1.1706 37.841 3.20923L42.9637 40.1218C43.2466 42.1604 41.8441 44.0453 39.831 44.3319L14.3162 47.9633C12.3031 48.2498 10.4419 46.8294 10.159 44.7908L5.03628 7.87818Z" fill="url(#paint0_linear_1287_1214)"/>
<path d="M6.85877 7.6188C6.71731 6.59948 7.41859 5.65703 8.42512 5.51378L33.9399 1.88237C34.9465 1.73911 35.8771 2.4493 36.0186 3.46861L41.1412 40.3812C41.2827 41.4005 40.5814 42.343 39.5749 42.4862L14.0601 46.1176C13.0535 46.2609 12.1229 45.5507 11.9814 44.5314L6.85877 7.6188Z" fill="white"/>
<path d="M33.1857 14.9195L25.8505 34.1576C25.6991 34.5547 25.1763 34.63 24.9177 34.2919L12.3343 17.8339C12.0526 17.4655 12.3217 16.9339 12.7806 16.9524L22.9053 17.3607C22.9698 17.3633 23.0344 17.3541 23.0956 17.3337L32.5088 14.1992C32.9431 14.0546 33.3503 14.4878 33.1857 14.9195Z" fill="url(#paint1_linear_1287_1214)"/>
<path d="M27.0251 12.5756L19.9352 15.0427C19.8187 15.0832 19.7444 15.1986 19.7546 15.3231L20.3916 23.063C20.4066 23.2453 20.5904 23.3628 20.7588 23.2977L22.7226 22.5392C22.9064 22.4682 23.1021 22.6138 23.0905 22.8128L22.9102 25.8903C22.8982 26.0974 23.1093 26.2436 23.295 26.1567L24.4948 25.5953C24.6808 25.5084 24.892 25.6549 24.8795 25.8624L24.5855 30.6979C24.5671 31.0004 24.9759 31.1067 25.1013 30.8321L25.185 30.6487L29.4298 17.8014C29.5008 17.5863 29.2968 17.3809 29.0847 17.454L27.0519 18.1547C26.8609 18.2205 26.6675 18.0586 26.6954 17.8561L27.3823 12.8739C27.4103 12.6712 27.2163 12.5091 27.0251 12.5756Z" fill="url(#paint2_linear_1287_1214)"/>
<defs>
<linearGradient id="paint0_linear_1287_1214" x1="6.48163" y1="1.9759" x2="39.05" y2="48.2064" gradientUnits="userSpaceOnUse">
<stop stop-color="#49C7FF"/>
<stop offset="1" stop-color="#BD36FF"/>
</linearGradient>
<linearGradient id="paint1_linear_1287_1214" x1="11.8848" y1="16.4266" x2="26.7246" y2="31.4177" gradientUnits="userSpaceOnUse">
<stop stop-color="#41D1FF"/>
<stop offset="1" stop-color="#BD34FE"/>
</linearGradient>
<linearGradient id="paint2_linear_1287_1214" x1="21.8138" y1="13.7046" x2="26.2464" y2="28.8069" gradientUnits="userSpaceOnUse">
<stop stop-color="#FFEA83"/>
<stop offset="0.0833333" stop-color="#FFDD35"/>
<stop offset="1" stop-color="#FFA800"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

@ -172,9 +172,9 @@ title 是图片的标题,当鼠标移到图片上时显示的内容。
<!-- 图片可以被链接包裹 -->
```
<!-- ::: details 示例
::: details 示例
![vite](./logo.svg 'vite')
::: -->
:::
## 列表 {#list}

@ -210,6 +210,25 @@ console.log('Hello, VitePress!')
:::
此外,您可以通过在站点配置中添加以下内容来全局设置自定义标题,如果不是用英语书写,这会很有帮助:
```ts
// config.ts
export default defineConfig({
// ...
markdown: {
container: {
tipLabel: '提示',
warningLabel: '警告',
dangerLabel: '危险',
infoLabel: '信息',
detailsLabel: '详细信息',
},
},
// ...
})
```
### `raw`
这是一个特殊的容器,可以用来防止与 VitePress 的样式和路由冲突。这在记录组件库时特别有用。你可能还想查看 [whyframe](https://whyframe.dev/docs/integrations/vitepress) 以获得更好的隔离。
@ -224,32 +243,29 @@ Wraps in a <div class="vp-raw">
`vp-raw` class 也可以直接用于元素。样式隔离目前是可选的:
::: details
- 使用你喜欢的包管理器来安装 `postcss`
- 使用你喜欢的包管理器来安装需要的依赖项:
```sh
$ npm install -D postcss postcss-prefix-selector
```
- 创建 `docs/.postcssrc.cjs` 并将以下内容
```js
module.exports = {
plugins: {
'postcss-prefix-selector': {
prefix: ':not(:where(.vp-raw *))',
includeFiles: [/vp-doc\.css/],
transform(prefix, _selector) {
const [selector, pseudo = ''] = _selector.split(/(:\S*)$/)
return selector + prefix + pseudo
},
},
},
}
```
```sh
$ npm add -D postcss
```
:::
- 创建 `docs/postcss.config.mjs` 并将以下内容
```js
import { postcssIsolateStyles } from 'vitepress'
export default {
plugins: [postcssIsolateStyles()],
}
```
它在底层使用 [`postcss-prefix-selector`](https://github.com/postcss/postcss-load-config)。你可以像这样传递它的选项:
```js
postcssIsolateStyles({
includeFiles: [/vp-doc\.css/], // 默认 /base\.css/
})
```
## 代码块中的语法高亮 {#syntax-highlighting-in-code-blocks}
@ -509,6 +525,8 @@ export default {
你可以在你的代码块中添加 `:line-numbers` / `:no-line-numbers` 标记来覆盖在配置中的设置。
您还可以通过在 `:line-numbers` 之后添加 `=` 来自定义起始行号。例如, `:line-numbers=2` 表示代码块中的行号将从“2”开始。
**输入**
````md
@ -523,6 +541,12 @@ const line3 = 'This is line 3'
const line2 = 'This is line 2'
const line3 = 'This is line 3'
```
```ts:line-numbers=2 {1}
// line-numbers is enabled and start from 2
const line3 = 'This is line 3'
const line4 = 'This is line 4'
```
````
**输出**
@ -539,6 +563,12 @@ const line2 = 'This is line 2'
const line3 = 'This is line 3'
```
```ts:line-numbers=2 {1}
// line-numbers is enabled and start from 2
const line3 = 'This is line 3'
const line4 = 'This is line 4'
```
## 导入代码片段 {#import-code-snippets}
你可以通过下面的语法来从现有文件中导入代码片段:
@ -780,19 +810,64 @@ Some getting started stuff.
注意!如果你指定的文件不存在,这将不会产生错误。因此,在使用这个功能的时候请保证内容按预期呈现。
:::
## Math Equations
This is currently opt-in. 要启用它, 你需要安装 `markdown-it-mathjax3`,在配置文件中设置`markdown.math` 为 `true`
```sh
npm add -D markdown-it-mathjax3
```
```ts
// .vitepress/config.ts
export default {
markdown: {
math: true,
},
}
```
**输入**
```md
当 $a \ne 0$, $(ax^2 + bx + c = 0)$ 有两个解,它们是
$$ x = {-b \pm \sqrt{b^2-4ac} \over 2a} $$
**Maxwell's 方程组:**
| 方程 | 描述 |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- |
| $\nabla \cdot \vec{\mathbf{B}} = 0$ | divergence of $\vec{\mathbf{B}}$ is zero |
| $\nabla \times \vec{\mathbf{E}}\, +\, \frac1c\, \frac{\partial\vec{\mathbf{B}}}{\partial t} = \vec{\mathbf{0}}$ | curl of $\vec{\mathbf{E}}$ is proportional to the rate of change of $\vec{\mathbf{B}}$ |
| $\nabla \times \vec{\mathbf{B}} -\, \frac1c\, \frac{\partial\vec{\mathbf{E}}}{\partial t} = \frac{4\pi}{c}\vec{\mathbf{j}} \nabla \cdot \vec{\mathbf{E}} = 4 \pi \rho$ | _wha?_ |
```
**输出**
当 $a \ne 0$, $(ax^2 + bx + c = 0)$ 有两个解,它们是
$$ x = {-b \pm \sqrt{b^2-4ac} \over 2a} $$
**Maxwell's 方程组:**
| 方程 | 描述 |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- |
| $\nabla \cdot \vec{\mathbf{B}} = 0$ | divergence of $\vec{\mathbf{B}}$ is zero |
| $\nabla \times \vec{\mathbf{E}}\, +\, \frac1c\, \frac{\partial\vec{\mathbf{B}}}{\partial t} = \vec{\mathbf{0}}$ | curl of $\vec{\mathbf{E}}$ is proportional to the rate of change of $\vec{\mathbf{B}}$ |
| $\nabla \times \vec{\mathbf{B}} -\, \frac1c\, \frac{\partial\vec{\mathbf{E}}}{\partial t} = \frac{4\pi}{c}\vec{\mathbf{j}} \nabla \cdot \vec{\mathbf{E}} = 4 \pi \rho$ | _wha?_ |
## 高级配置 {#advanced-configuration}
VitePress 使用 [markdown-it](https://github.com/markdown-it/markdown-it) 作为 Markdown 渲染器。上面提到的很多拓展功能都是通过自定义插件实现的。你可以使用 `.vitepress/config.js` 中的 `markdown` 选项来进一步自定义 `markdown-it` 实例。
```js
const anchor = require('markdown-it-anchor')
import markdownItAnchor from 'markdown-it-anchor'
import markdownItFoo from 'markdown-it-foo'
module.exports = {
markdown: {
// options for markdown-it-anchor
// https://github.com/valeriangalliat/markdown-it-anchor#usage
anchor: {
permalink: anchor.permalink.headerLink(),
permalink: markdownItAnchor.permalink.headerLink(),
},
// options for @mdit-vue/plugin-toc
@ -800,8 +875,8 @@ module.exports = {
toc: { level: [1, 2] },
config: (md) => {
// use more markdown-it plugins!
md.use(require('markdown-it-xxx'))
// 使用更多 markdown-it 插件
md.use(markdownItFoo)
},
},
}

@ -95,7 +95,33 @@ src/getting-started.md --> /getting-started.html
[Getting Started](./getting-started.html)
```
在[资源处理](asset-handling)中了解有关链接到资源(例如图像)的更多信息。
在[资源处理](./asset-handling)中了解有关链接到资源(例如图像)的更多信息。
### 链接到非 vitepress 页面 {#linking-to-non-vitepress-pages}
如果您想链接到网站中不是由 VitePress 生成的页面,您需要使用完整的 URL在新选项卡中打开或明确指定 target
**Input**
```md
[链接到 pure.html](/pure.html){target="\_self"}
```
**Output**
[链接到 pure.html](/pure.html){target="\_self"}
::: tip 注意
在 Markdown 链接中,`base` 会自动添加到 URL 前面。这意味着,如果您想链接到 `base` 之外的页面,则链接中需要类似 `../../pure.html` 的内容(由浏览器相对于当前页面解析)。
或者,您可以直接使用锚标记语法:
```md
<a href="/pure.html" target="_self">Link to pure.html</a>
```
:::
## 生成简洁的 URL {#generating-clean-url}

@ -52,6 +52,7 @@ if (!import.meta.env.SSR) {
```js
// .vitepress/theme/index.js
/** @type {import('vitepress').Theme} */
export default {
// ...
async enhanceApp({ app }) {
@ -63,6 +64,23 @@ export default {
}
```
如果你使用 TypeScript:
```ts
// .vitepress/theme/index.ts
import type { Theme } from 'vitepress'
export default {
// ...
async enhanceApp({ app }) {
if (!import.meta.env.SSR) {
const plugin = await import('plugin-that-access-window-on-import')
app.use(plugin)
}
},
} satisfies Theme
```
### `defineClientComponent` {#`defineclientcomponent`}
VitePress 为导入 Vue 组件提供了一个方便的辅助函数,该组件可以在导入时访问浏览器 API。

@ -11,10 +11,13 @@ hero:
actions:
- theme: brand
text: 认识 VitePress
link: /zh/guide/getting-started
link: /guide/getting-started
- theme: alt
text: GitHub
link: https://github.com/vuejs/vitepress
image:
src: /vitepress-logo-large.webp
alt: VitePress
features:
- icon: 📝
@ -30,3 +33,25 @@ features:
title: 速度真的很快!
details: 采用静态 HTML 实现快速的页面初次加载,使用客户端路由实现快速的页面切换导航。
---
<style>
:root {
--vp-home-hero-name-color: transparent;
--vp-home-hero-name-background: -webkit-linear-gradient(120deg, #bd34fe 30%, #41d1ff);
--vp-home-hero-image-background-image: linear-gradient(-45deg, #bd34fe 50%, #47caff 50%);
--vp-home-hero-image-filter: blur(44px);
}
@media (min-width: 640px) {
:root {
--vp-home-hero-image-filter: blur(56px);
}
}
@media (min-width: 960px) {
:root {
--vp-home-hero-image-filter: blur(68px);
}
}
</style>

@ -7,17 +7,18 @@
你可以使用全局组件 `Badge`
```html
### Title <Badge type="info" text="default" />
### Title <Badge type="tip" text="^1.9.0" />
### Title <Badge type="warning" text="beta" />
### Title <Badge type="danger" text="caution" />
### Title <Badge type="info" text="default" /> ### Title <Badge type="tip" text="^1.9.0" /> ### Title <Badge type="warning" text="beta" /> ### Title
<Badge type="danger" text="caution" />
```
上面的代码渲染如下:
### Title <Badge type="info" text="default" />
### Title <Badge type="tip" text="^1.9.0" />
### Title <Badge type="warning" text="beta" />
### Title <Badge type="info" text="default" />
### Title <Badge type="tip" text="^1.9.0" />
### Title <Badge type="warning" text="beta" />
### Title <Badge type="danger" text="caution" />
## 自定义 `children` {#custom-children}
@ -25,46 +26,32 @@
`<Badge>` 接受 `子节点`, 这将显示在徽标中。
```html
### Title <Badge type="info">custom element</Badge>
### Title <Badge type="info">custom element</Badge>
```
### Title <Badge type="info">custom element</Badge>
## 自定义不同类型徽标的背景色 {#customize-type-color}
你可以通过覆盖 css 变量 `background-color` 来自定义不同类型 `<Badge />` 的背景色。以下是默认值。
你可以通过覆写 css 来自定义不同类型 `<Badge />` 的样式。以下是默认值。
```css
:root {
--vp-badge-info-border: var(--vp-c-divider-light);
--vp-badge-info-text: var(--vp-c-text-2);
--vp-badge-info-bg: var(--vp-c-white-soft);
--vp-badge-tip-border: var(--vp-c-green-dimm-1);
--vp-badge-tip-text: var(--vp-c-green-darker);
--vp-badge-tip-bg: var(--vp-c-green-dimm-3);
--vp-badge-warning-border: var(--vp-c-yellow-dimm-1);
--vp-badge-warning-text: var(--vp-c-yellow-darker);
--vp-badge-warning-bg: var(--vp-c-yellow-dimm-3);
--vp-badge-danger-border: var(--vp-c-red-dimm-1);
--vp-badge-danger-text: var(--vp-c-red-darker);
--vp-badge-danger-bg: var(--vp-c-red-dimm-3);
}
.dark {
--vp-badge-info-border: var(--vp-c-divider-light);
--vp-badge-info-bg: var(--vp-c-black-mute);
--vp-badge-info-border: transparent;
--vp-badge-info-text: var(--vp-c-text-2);
--vp-badge-info-bg: var(--vp-c-default-soft);
--vp-badge-tip-border: var(--vp-c-green-dimm-2);
--vp-badge-tip-text: var(--vp-c-green-light);
--vp-badge-tip-border: transparent;
--vp-badge-tip-text: var(--vp-c-brand-1);
--vp-badge-tip-bg: var(--vp-c-brand-soft);
--vp-badge-warning-border: var(--vp-c-yellow-dimm-2);
--vp-badge-warning-text: var(--vp-c-yellow-light);
--vp-badge-warning-border: transparent;
--vp-badge-warning-text: var(--vp-c-warning-1);
--vp-badge-warning-bg: var(--vp-c-warning-soft);
--vp-badge-danger-border: var(--vp-c-red-dimm-2);
--vp-badge-danger-text: var(--vp-c-red-light);
--vp-badge-danger-border: transparent;
--vp-badge-danger-text: var(--vp-c-danger-1);
--vp-badge-danger-bg: var(--vp-c-danger-soft);
}
```
@ -74,10 +61,10 @@
```ts
interface Props {
// When `<slot>` is passed, this value gets ignored.
text?: string
// When `<slot>` is passed, this value gets ignored.
text?: string
// Defaults to `tip`.
type?: 'info' | 'tip' | 'warning' | 'danger'
// Defaults to `tip`.
type?: 'info' | 'tip' | 'warning' | 'danger'
}
```

@ -67,7 +67,7 @@ export default {
导航菜单项的配置。 你可以在[默认主题: 导航栏](./default-theme-nav#navigation-links) 了解更多详情。
```js
```ts
export default {
themeConfig: {
nav: [
@ -115,7 +115,7 @@ interface NavItemWithChildren {
侧边栏菜单项的配置。 你可以在[默认主题: 侧边栏](./default-theme-sidebar) 了解更多详情。
```js
```ts
export default {
themeConfig: {
sidebar: [
@ -169,34 +169,41 @@ export type SidebarItem = {
## 大纲开关 {#aside}
- key: `aside`
- Type: `boolean`
- Type: `boolean | 'left'`
- Default: `true`
- 每个页面可以通过 [frontmatter](./frontmatter-config#aside) 覆写
将此值设置为 `false` 可禁用 aside(大纲) 容器。
将此值设置为 `false` 可禁用 aside(大纲) 容器。\
将此值设置为 `true` 将在页面右侧渲染。\
将此值设置为 `left` 将在页面左侧渲染。
## 大纲层级 {#outline}
如果您想对所有页面禁用它,您应该使用 `outline: false`
### 大纲层级 {#outline}
- key: `outline`
- Type: `number | [number, number] | 'deep' | false`
- Default: `2`
- 每个页面可以通过 [frontmatter](./frontmatter-config#outline) 覆写
配置在大纲中显示的标题级别。你可以通过传递一个数字来指定一个特定的级别,或者你可以通过传递一个包含下限和上限的元组来提供一个级别范围。当传递等于 `[2, 6]``deep` 时,除 `h1` 外,所有标题级别都显示在轮廓中。设置 `false` 以隐藏轮廓。
## 大纲标题 {#outline-title}
将此值设置为 `false` 可禁止渲染大纲容器。更多详情请参考该接口:
- key: `outlineTitle`
- Type: `string`
- Default: `On this page`
可用于自定义右侧边栏的标题(在大纲链接的顶部)。 这在用另一种语言编写文档时很有用。
```ts
interface Outline {
/**
* 大纲中显示的标题级别。
* 单个数字表示仅显示该级别的标题。
* 如果传递一个元组,则第一个数字是最小级别,第二个数字是最大级别。
* `'deep'` 和`[2, 6]` 等效, 这意味着 `<h2>``<h6>` 都会展示。
*
* @default 2
*/
level?: number | [number, number] | 'deep'
```js
export default {
themeConfig: {
outlineTitle: 'In hac pagina',
},
/**
* 要显示在大纲上的标题。
*
* @default 'On this page'
*/
label?: string
}
```
@ -207,7 +214,7 @@ export default {
你可以定义此选项以在导航栏中展示带有图标的社交帐户链接。
```js
```ts
export default {
themeConfig: {
socialLinks: [
@ -271,7 +278,7 @@ export interface Footer {
编辑链接可让你显示链接以编辑 Git 管理服务(例如 GitHub 或 GitLab上的页面。 有关详细信息,请参阅 [默认主题:编辑链接](./default-theme-edit-link)。
```js
```ts
export default {
themeConfig: {
editLink: {
@ -321,7 +328,7 @@ export interface LastUpdatedOptions {
* @default
* { dateStyle: 'short', timeStyle: 'short' }
*/
formatOptions?: Intl.DateTimeFormatOptions
formatOptions?: Intl.DateTimeFormatOptions & { forceLocale?: boolean }
// calendar?: string | undefined;
// dayPeriod?: "narrow" | "short" | "long" | undefined;
// numberingSystem?: string | undefined;
@ -377,7 +384,7 @@ Learn more in [Default Theme: Carbon Ads](./default-theme-carbon-ads)
可用于自定义出现在上一篇和下一篇链接上方的文本。 如果不是用英语编写文档,这很有帮助。也可用于全局禁用上一个/下一个链接。如果您想选择性地启用/禁用上一个/下一个链接,可以使用 [frontmatter](./default-theme-prev-next-links)。
```js
```ts
export default {
themeConfig: {
docFooter: {

@ -71,7 +71,7 @@ interface HeroAction {
### 自定义 name 的颜色 {#customizing-the-name-color}
VitePress 通过 (`--vp-c-brand`) 设置 `name` 的颜色 .但是,你可以通过覆写 `--vp-home-hero-name-color` 变量来自定义此颜色。
VitePress 通过 (`--vp-c-brand-1`) 设置 `name` 的颜色 .但是,你可以通过覆写 `--vp-home-hero-name-color` 变量来自定义此颜色。
```css
:root {

@ -24,5 +24,4 @@ lastUpdated: false
---
```
Also refer [Default Theme: Last Updated](./default-theme-last-updated#last-updated) for more details. Any truthy value at theme-level will also enable the feature unless explicitly disabled at site or page level.
另请参阅[默认主题:上次更新](./default-theme-last-updated#last-updated) 了解更多详细信息。主题级别的任何真值也将启用该功能,除非在站点或页面级别明确禁用。

@ -41,3 +41,27 @@ layout: doc
## 无布局 {#no-layout}
如果你不想要任何布局,你可以通过 frontmatter 传递 `layout: false`。如果你想要一个完全可自定义的登录页面(默认情况下没有任何侧边栏、导航栏或页脚),此选项很有用。
## 自定义布局 {#custom-layout}
你也可以使用自定义布局:
```md
---
layout: foo
---
```
这将在上下文中查找注册名为 `foo` 的组件。例如,你可以在 `.vitepress/theme/index.ts`中全局注册您的组件:
```ts
import DefaultTheme from 'vitepress/theme'
import Foo from './Foo.vue'
export default {
extends: DefaultTheme,
enhanceApp({ app }) {
app.component('foo', Foo)
},
}
```

@ -101,9 +101,38 @@ export default defineConfig({
查阅更多 [MiniSearch docs](https://lucaong.github.io/minisearch/classes/_minisearch_.minisearch.html).
### 从搜索中排除页面 {#excluding-pages-from-search}
### 自定义渲染内容 {#custom-content-renderer}
您可以在索引之前自定义用于渲染 Markdown 内容的函数:
```ts
import { defineConfig } from 'vitepress'
export default defineConfig({
themeConfig: {
search: {
provider: 'local',
options: {
/**
* @param {string} src
* @param {import('vitepress').MarkdownEnv} env
* @param {import('markdown-it')} md
*/
_render(src, env, md) {
// return html string
},
},
},
},
})
```
该函数将从客户端站点数据中剥离,因此您可以在其中使用 Node.js API。
#### 示例:从搜索中排除页面 {#example-excluding-pages-from-search}
您可以通过将 `search: false` 添加到页面的 frontmatter 来从搜索中排除页面。或者,您还可以将 `exclude` 函数传递给 `themeConfig.search.options`,以根据相对于 `srcDir` 的路径排除页面:
您可以通过将 `search: false` 添加到页面的 `frontmatter` 来从搜索中排除页面。或者:
```ts
import { defineConfig } from 'vitepress'
@ -111,8 +140,39 @@ import { defineConfig } from 'vitepress'
export default defineConfig({
themeConfig: {
search: {
provider: 'local',
options: {
exclude: (path) => path.startsWith('/some/path'),
_render(src, env, md) {
const html = md.render(src, env)
if (env.frontmatter?.search === false) return ''
if (env.relativePath.startsWith('some/path')) return ''
return html
},
},
},
},
})
```
::: warning 注意
如果提供了自定义的 `_render` 函数,您需要自己处理 `search: false` 的 frontmatter。此外在调用 `md.render` 之前,`env` 对象不会完全填充,因此对可选 `env` 属性(如 `frontmatter` )的任何检查都应该在此之后完成。
:::
#### 示例:转换内容-添加锚点{#example-transforming-content-adding-anchors}
```ts
import { defineConfig } from 'vitepress'
export default defineConfig({
themeConfig: {
search: {
provider: 'local',
options: {
_render(src, env, md) {
const html = md.render(src, env)
if (env.frontmatter?.title) return md.render(`# ${env.frontmatter.title}`) + html
return html
},
},
},
},

@ -2,32 +2,32 @@
import { VPTeamMembers } from 'vitepress/theme'
const members = [
{
avatar: 'https://github.com/yyx990803.png',
name: 'Evan You',
title: 'Creator',
links: [
{ icon: 'github', link: 'https://github.com/yyx990803' },
{ icon: 'twitter', link: 'https://twitter.com/youyuxi' }
]
},
{
avatar: 'https://github.com/kiaking.png',
name: 'Kia King Ishii',
title: 'Developer',
links: [
{ icon: 'github', link: 'https://github.com/kiaking' },
{ icon: 'twitter', link: 'https://twitter.com/KiaKing85' }
]
}
// {
// avatar: 'https://avatars.githubusercontent.com/u/50388827?v=4',
// name: 'VanchKong',
// title: 'Translator',
// avatar: 'https://github.com/yyx990803.png',
// name: 'Evan You',
// title: 'Creator',
// links: [
// { icon: 'github', link: 'https://github.com/vanchKong' },
// { icon: 'github', link: 'https://github.com/yyx990803' },
// { icon: 'twitter', link: 'https://twitter.com/youyuxi' }
// ]
// },
// {
// avatar: 'https://github.com/kiaking.png',
// name: 'Kia King Ishii',
// title: 'Developer',
// links: [
// { icon: 'github', link: 'https://github.com/kiaking' },
// { icon: 'twitter', link: 'https://twitter.com/KiaKing85' }
// ]
// }
{
avatar: 'https://avatars.githubusercontent.com/u/50388827?v=4',
name: 'VanchKong',
title: 'Translator',
links: [
{ icon: 'github', link: 'https://github.com/vanchKong' },
]
}
]
</script>

@ -166,15 +166,15 @@ aside: false
- Type: `number | [number, number] | 'deep' | false`
- Default: `2`
大纲中显示的标题级别。它与 [config.themeConfig.outline](./default-theme-config#outline) 相同,它会覆盖主题配置。
大纲中显示的标题级别。它与 [config.themeConfig.outline.level](./default-theme-config#outline) 相同,它会覆盖站点级的配置。
### 最近更新时间 {#lastupdated}
- key: `lastUpdated`
- Type: `boolean`
- Type: `boolean | Date`
- Default: `true`
是否在当前页面的页脚中显示[最近更新时间](./default-theme-last-updated)的文本。
是否在当前页面的页脚中显示[最近更新时间](./default-theme-last-updated)的文本。如果指定了日期时间,则会显示该日期时间而不是上次 git 修改的时间戳。
```yaml
---

@ -10,7 +10,7 @@ Site config 可以定义站点的全局设置。App config 配置选项适用于
### 配置解析 {#config-resolution}
配置文件总是从 `<root>/.vitepress/config.[ext]` 解析,其中 `<root>` 是你的 VitePress [项目根目录](../guide/routing#root-and-source-directory)`[ext]` 是支持的文件扩展名之一。开箱即用地支持 TypeScript。支持的扩展名包括 `.js`、`.ts`、`.cjs`、`.mjs`、`.cts` 和 `.mts`
配置文件总是从 `<root>/.vitepress/config.[ext]` 解析,其中 `<root>` 是你的 VitePress [项目根目录](../guide/routing#root-and-source-directory)`[ext]` 是支持的文件扩展名之一。开箱即用地支持 TypeScript。支持的扩展名包括 `.js`、`.ts`、`.mjs` 和 `.mts`
建议在配置文件中使用 ES 模块语法。配置文件应该默认导出一个对象:
@ -161,17 +161,45 @@ export default {
Additional elements to render in the `<head>` tag in the page HTML. The user-added tags are rendered before the closing `head` tag, after VitePress tags.
:::
```ts
type HeadConfig = [string, Record<string, string>] | [string, Record<string, string>, string]
```
#### 示例:添加一个图标 {#example-adding-a-favicon}
```ts
export default {
head: [['link', { rel: 'icon', href: '/favicon.ico' }]],
} // put favicon.ico in public directory, if base is set, use /base/favicon.ico
/* Would render:
<link rel="icon" href="/favicon.ico">
*/
```
#### 示例:添加谷歌字体 {#example-adding-google-fonts}
```ts
export default {
head: [
[
'link',
{ rel: 'preconnect', href: 'https://fonts.gstatic.com', crossorigin: '' },
// would render:
//
// <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
],
['link', { rel: 'preconnect', href: 'https://fonts.googleapis.com' }],
['link', { rel: 'preconnect', href: 'https://fonts.gstatic.com', crossorigin: '' }],
['link', { href: 'https://fonts.googleapis.com/css2?family=Roboto&display=swap', rel: 'stylesheet' }],
],
}
/* 将会渲染成:
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Roboto&display=swap" rel="stylesheet">
*/
```
#### 示例:添加一个 serviceWorker {#example-registering-a-service-worker}
```ts
export default {
head: [
[
'script',
{ id: 'register-sw' },
@ -180,22 +208,47 @@ export default {
navigator.serviceWorker.register('/sw.js')
}
})()`,
// would render:
//
// <script id="register-sw">
// ;(() => {
// if ('serviceWorker' in navigator) {
// navigator.serviceWorker.register('/sw.js')
// }
// })()
// </script>
],
],
}
/* 将会渲染成:
<script id="register-sw">
;(() => {
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js')
}
})()
</script>
*/
```
#### 示例:使用谷歌分析 {#example-using-google-analytics}
```ts
type HeadConfig = [string, Record<string, string>] | [string, Record<string, string>, string]
export default {
head: [
['script', { async: '', src: 'https://www.googletagmanager.com/gtag/js?id=TAG_ID' }],
[
'script',
{},
`window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'TAG_ID');`,
],
],
}
/* 将会渲染成:
<script async src="https://www.googletagmanager.com/gtag/js?id=TAG_ID"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'TAG_ID');
</script>
*/
```
### 语言 {#lang}
@ -247,7 +300,7 @@ export default {
- key: `rewrites`
- Type: `Record<string, string>`
自定义目录 <-> URL 映射。详细信息请参阅[路由:路由重写](../guide/routing#route-rewrites)。
自定义目录 &lt;-&gt; URL 映射。详细信息请参阅[路由:路由重写](../guide/routing#route-rewrites)。
```ts
export default {
@ -380,7 +433,7 @@ When set to `true`, the production app will be built in [MPA Mode](../guide/mpa-
### 外观 {#appearance}
- key: `appearance`
- Type: `boolean | 'dark'`
- Type: `boolean | 'dark' | 'force-dark' | import('@vueuse/core').UseDarkOptions`
- Default: `true`
是否启用深色模式(通过将 `.dark` 类添加到 `<html>` 元素)。
@ -391,6 +444,8 @@ When set to `true`, the production app will be built in [MPA Mode](../guide/mpa-
此选项注入一个内联脚本,使用 `vitepress-theme-appearance` key 从本地存储恢复用户设置。这确保在呈现页面之前应用 `.dark` 类以避免闪烁。
`appearance.initialValue` 只能是 `'dark' | undefined`。 不支持 Refs 或 getters。
### 最近更新时间 {#lastupdated}
- key: `lastUpdated`
@ -412,19 +467,9 @@ When set to `true`, the production app will be built in [MPA Mode](../guide/mpa-
```js
export default {
markdown: {
theme: 'material-theme-palenight',
lineNumbers: true,
// adjust how header anchors are generated,
// useful for integrating with tools that use different conventions
anchor: {
slugify(str) {
return encodeURIComponent(str)
},
},
},
markdown: {...}
}
```
以下是你可以在此对象中可配置的所有选项:
@ -477,8 +522,24 @@ interface MarkdownOptions extends MarkdownIt.Options {
// See: https://github.com/mdit-vue/mdit-vue/tree/main/packages/plugin-toc#options
toc?: TocPluginOptions
// @mdit-vue/plugin-component plugin options.
// See: https://github.com/mdit-vue/mdit-vue/tree/main/packages/plugin-component#options
component?: ComponentPluginOptions
// Configure the Markdown-it instance.
config?: (md: MarkdownIt) => void
// Same as `config` but will be applied before all other plugins.
preConfig?: (md: MarkdownIt) => void
// Disable cache (experimental)
cache?: boolean
// Math support (experimental)
// You need to install `markdown-it-mathjax3` and set `math` to `true` to enable it.
// You can also pass options to `markdown-it-mathjax3` here.
// See: https://github.com/tani/markdown-it-mathjax3#customization
math?: any
}
```
@ -570,7 +631,7 @@ interface SSGContext {
`transformHead` 是一个构建钩子,用于在生成每个页面之前转换 head。它将允许你添加无法静态添加到你的 VitePress 配置中的 head entries。你只需要返回额外的 entries它们将自动与现有 entries 合并。
::: warning 警告
不要改变 `ctx` 中的任何东西。
不要改变 `context` 中的任何东西。
:::
```ts
@ -595,15 +656,32 @@ interface TransformContext {
}
```
请注意,仅在静态生成站点时才会调用此挂钩。在开发期间不会调用它。如果您需要在开发期间添加动态头条目,您可以使用 [`transformPageData`](#transformpagedata) 钩子来替代:
```ts
export default {
transformPageData(pageData) {
pageData.frontmatter.head ??= []
pageData.frontmatter.head.push([
'meta',
{
name: 'og:title',
content: pageData.frontmatter.layout === 'home' ? `VitePress` : `${pageData.title} | VitePress`,
},
])
},
}
```
### transformHtml
- key: `transformHtml`
- Type: `(code: string, id: string, ctx: TransformContext) => Awaitable<string | void>`
- Type: `(code: string, id: string, context: TransformContext) => Awaitable<string | void>`
`transformHtml` 是一个构建钩子,用于在保存到磁盘之前转换每个页面的内容。
::: warning 警告
不要改变 `ctx` 中的任何东西。另外,修改 html 内容可能会导致运行时出现 hydration 问题。
不要改变 `context` 中的任何东西。另外,修改 html 内容可能会导致运行时出现 hydration 问题。
:::
```ts
@ -617,12 +695,12 @@ export default {
### transformPageData
- key: `transformPageData`
- Type: `(pageData: PageData, ctx: TransformPageContext) => Awaitable<Partial<PageData> | { [key: string]: any } | void>`
- Type: `(pageData: PageData, context: TransformPageContext) => Awaitable<Partial<PageData> | { [key: string]: any } | void>`
`transformPageData` 是一个钩子,用于转换每个页面的 `pageData`。你可以直接改变 `pageData` 或返回将合并到 `PageData` 中的更改值。
::: warning 警告
不要改变 `ctx` 中的任何东西。
不要改变 `context` 中的任何东西。请注意,这可能会影响开发服务器的性能,特别是当您在钩子中有一些网络请求或大量计算(例如生成图像)时。您可以通过判断 `process.env.NODE_ENV === 'production'` 匹配符合条件的情况。
:::
```ts

@ -1,5 +1,5 @@
[build.environment]
NODE_VERSION = "16"
NODE_VERSION = "18"
[build]
publish = "docs/.vitepress/dist"

@ -1,16 +1,15 @@
{
"name": "vitepress",
"version": "1.0.0-beta.7",
"version": "1.0.0-rc.24",
"description": "Vite & Vue powered static site generator",
"type": "module",
"packageManager": "pnpm@8.6.11",
"packageManager": "pnpm@8.9.2",
"main": "dist/node/index.js",
"types": "types/index.d.ts",
"exports": {
".": {
"types": "./types/index.d.ts",
"import": "./dist/node/index.js",
"require": "./dist/node-cjs/index.cjs"
"default": "./dist/node/index.js"
},
"./dist/*": "./dist/*",
"./package.json": "./package.json",
@ -91,96 +90,110 @@
"release": "node scripts/release.js"
},
"dependencies": {
"@docsearch/css": "^3.5.1",
"@docsearch/js": "^3.5.1",
"@vitejs/plugin-vue": "^4.2.3",
"@vue/devtools-api": "^6.5.0",
"@vueuse/core": "^10.3.0",
"@vueuse/integrations": "^10.3.0",
"body-scroll-lock": "4.0.0-beta.0",
"focus-trap": "^7.5.2",
"@docsearch/css": "^3.5.2",
"@docsearch/js": "^3.5.2",
"@types/markdown-it": "^13.0.4",
"@vitejs/plugin-vue": "4.3.1",
"@vue/devtools-api": "^6.5.1",
"@vueuse/core": "^10.5.0",
"@vueuse/integrations": "^10.5.0",
"focus-trap": "^7.5.4",
"mark.js": "8.11.1",
"minisearch": "^6.1.0",
"shiki": "^0.14.3",
"vite": "^4.4.8",
"vue": "^3.3.4"
"shiki": "^0.14.5",
"vite": "^4.5.0",
"vue": "^3.3.6"
},
"peerDependencies": {
"markdown-it-mathjax3": "^4.3.2",
"postcss": "^8.4.31"
},
"peerDependenciesMeta": {
"markdown-it-mathjax3": {
"optional": true
},
"postcss": {
"optional": true
}
},
"devDependencies": {
"@clack/prompts": "^0.6.3",
"@mdit-vue/plugin-component": "^0.12.0",
"@mdit-vue/plugin-frontmatter": "^0.12.0",
"@mdit-vue/plugin-headers": "^0.12.0",
"@mdit-vue/plugin-sfc": "^0.12.0",
"@mdit-vue/plugin-title": "^0.12.0",
"@mdit-vue/plugin-toc": "^0.12.0",
"@mdit-vue/shared": "^0.12.0",
"@rollup/plugin-alias": "^5.0.0",
"@rollup/plugin-commonjs": "^25.0.3",
"@rollup/plugin-json": "^6.0.0",
"@rollup/plugin-node-resolve": "^15.1.0",
"@rollup/plugin-replace": "^5.0.2",
"@types/body-scroll-lock": "^3.1.0",
"@types/compression": "^1.7.2",
"@types/cross-spawn": "^6.0.2",
"@types/debug": "^4.1.8",
"@types/escape-html": "^1.0.2",
"@types/fs-extra": "^11.0.1",
"@types/mark.js": "^8.11.8",
"@types/markdown-it": "^12.2.3",
"@types/markdown-it-attrs": "^4.1.0",
"@types/markdown-it-container": "^2.0.6",
"@types/markdown-it-emoji": "^2.0.2",
"@types/micromatch": "^4.0.2",
"@types/minimist": "^1.2.2",
"@types/node": "^20.4.6",
"@types/prompts": "^2.4.4",
"@vue/shared": "^3.3.4",
"@clack/prompts": "^0.7.0",
"@mdit-vue/plugin-component": "^1.0.0",
"@mdit-vue/plugin-frontmatter": "^1.0.0",
"@mdit-vue/plugin-headers": "^1.0.0",
"@mdit-vue/plugin-sfc": "^1.0.0",
"@mdit-vue/plugin-title": "^1.0.0",
"@mdit-vue/plugin-toc": "^1.0.0",
"@mdit-vue/shared": "^1.0.0",
"@rollup/plugin-alias": "^5.0.1",
"@rollup/plugin-commonjs": "^25.0.7",
"@rollup/plugin-json": "^6.0.1",
"@rollup/plugin-node-resolve": "^15.2.3",
"@rollup/plugin-replace": "^5.0.4",
"@types/compression": "^1.7.4",
"@types/cross-spawn": "^6.0.4",
"@types/debug": "^4.1.10",
"@types/escape-html": "^1.0.3",
"@types/fs-extra": "^11.0.3",
"@types/lodash.template": "^4.5.2",
"@types/mark.js": "^8.11.10",
"@types/markdown-it-attrs": "^4.1.2",
"@types/markdown-it-container": "^2.0.8",
"@types/markdown-it-emoji": "^2.0.3",
"@types/micromatch": "^4.0.4",
"@types/minimist": "^1.2.4",
"@types/node": "^20.8.7",
"@types/postcss-prefix-selector": "^1.16.2",
"@types/prompts": "^2.4.7",
"@vue/shared": "^3.3.6",
"chokidar": "^3.5.3",
"compression": "^1.7.4",
"conventional-changelog-cli": "^2",
"conventional-changelog-cli": "^4.1.0",
"cross-spawn": "^7.0.3",
"debug": "^4.3.4",
"esbuild": "^0.18.17",
"esbuild": "^0.19.5",
"escape-html": "^1.0.3",
"execa": "^7.2.0",
"execa": "^8.0.1",
"fast-glob": "^3.3.1",
"fs-extra": "^11.1.1",
"get-port": "^7.0.0",
"gray-matter": "^4.0.3",
"lint-staged": "^13.2.3",
"lint-staged": "^15.0.2",
"lodash.template": "^4.5.0",
"lru-cache": "^10.0.0",
"markdown-it": "^13.0.1",
"lru-cache": "^10.0.1",
"markdown-it": "^13.0.2",
"markdown-it-anchor": "^8.6.7",
"markdown-it-attrs": "^4.1.6",
"markdown-it-container": "^3.0.0",
"markdown-it-emoji": "^2.0.2",
"markdown-it-mathjax3": "^4.3.2",
"micromatch": "^4.0.5",
"minimist": "^1.2.8",
"nanoid": "^4.0.2",
"nanoid": "^5.0.2",
"npm-run-all": "^4.1.5",
"ora": "^7.0.1",
"path-to-regexp": "^6.2.1",
"picocolors": "^1.0.0",
"pkg-dir": "^7.0.0",
"playwright-chromium": "^1.36.2",
"playwright-chromium": "^1.39.0",
"polka": "1.0.0-next.22",
"prettier": "^3.0.1",
"postcss-prefix-selector": "^1.16.0",
"prettier": "^3.0.3",
"prompts": "^2.4.2",
"punycode": "^2.3.0",
"rimraf": "^5.0.1",
"rollup": "^3.27.0",
"rollup-plugin-dts": "^5.3.1",
"rollup-plugin-esbuild": "^5.0.0",
"rimraf": "^5.0.5",
"rollup": "^4.1.4",
"rollup-plugin-dts": "^6.1.0",
"rollup-plugin-esbuild": "^6.1.0",
"semver": "^7.5.4",
"shiki-processor": "^0.1.3",
"simple-git-hooks": "^2.9.0",
"sirv": "^2.0.3",
"sitemap": "^7.1.1",
"supports-color": "^9.4.0",
"typescript": "^5.1.6",
"vitest": "^0.34.1",
"vue-tsc": "^1.8.8",
"typescript": "^5.2.2",
"vitest": "^0.34.6",
"vue-tsc": "^1.8.19",
"wait-on": "^7.0.1"
},
"simple-git-hooks": {
@ -190,5 +203,10 @@
"*": [
"prettier --write --ignore-unknown"
]
},
"pnpm": {
"overrides": {
"ora>string-width": "^5"
}
}
}

File diff suppressed because it is too large Load Diff

@ -22,10 +22,10 @@ const r = (p: string) => resolve(ROOT, '..', p)
const external = [
...Object.keys(pkg.dependencies),
...Object.keys(pkg.peerDependencies),
...builtinModules.flatMap((m) =>
m.includes('punycode') ? [] : [m, `node:${m}`]
),
r('types/shared.d.ts')
)
]
const plugins = [
@ -42,7 +42,7 @@ const plugins = [
}),
commonjs(),
nodeResolve({ preferBuiltins: false }),
esbuild({ target: 'node14' }),
esbuild({ target: 'node18' }),
json()
]
@ -62,20 +62,12 @@ const esmBuild: RollupOptions = {
}
}
const cjsBuild: RollupOptions = {
input: [r('src/node/index.ts'), r('src/node/cli.ts')],
output: {
format: 'cjs',
dir: r('dist/node-cjs'),
entryFileNames: `[name].cjs`,
chunkFileNames: 'serve-[hash].cjs'
},
external,
plugins,
onwarn(warning, warn) {
if (warning.code !== 'EVAL') warn(warning)
}
}
const typesExternal = [
...external,
/\/vitepress\/(?!(dist|node_modules)\/).*\.d\.ts$/,
'source-map-js',
'fast-glob'
]
const nodeTypes: RollupOptions = {
input: r('src/node/index.ts'),
@ -83,7 +75,7 @@ const nodeTypes: RollupOptions = {
format: 'esm',
file: 'dist/node/index.d.ts'
},
external,
external: typesExternal,
plugins: [dts({ respectExternal: true })]
}
@ -93,7 +85,7 @@ const clientTypes: RollupOptions = {
format: 'esm',
file: 'dist/client/index.d.ts'
},
external,
external: typesExternal,
plugins: [
dts({ respectExternal: true }),
{
@ -110,11 +102,6 @@ const clientTypes: RollupOptions = {
const config = defineConfig([])
config.push(esmBuild)
if (PROD) {
config.push(cjsBuild)
}
config.push(nodeTypes)
config.push(clientTypes)

@ -37,6 +37,9 @@ export function useCodeGroups() {
current.classList.remove('active')
next.classList.add('active')
const label = group?.querySelector(`label[for="${el.id}"]`)
label?.scrollIntoView({ block: 'nearest' })
}
})
}

@ -8,7 +8,7 @@ import {
import type { Route } from '../router'
export function useUpdateHead(route: Route, siteDataByRouteRef: Ref<SiteData>) {
let managedHeadTags: HTMLElement[] = []
let managedHeadElements: (HTMLElement | undefined)[] = []
let isFirstUpdate = true
const updateHeadTags = (newTags: HeadConfig[]) => {
@ -19,13 +19,25 @@ export function useUpdateHead(route: Route, siteDataByRouteRef: Ref<SiteData>) {
return
}
managedHeadTags.forEach((el) => document.head.removeChild(el))
managedHeadTags = []
newTags.forEach((headConfig) => {
const el = createHeadElement(headConfig)
document.head.appendChild(el)
managedHeadTags.push(el)
const newElements: (HTMLElement | undefined)[] =
newTags.map(createHeadElement)
managedHeadElements.forEach((oldEl, oldIndex) => {
const matchedIndex = newElements.findIndex(
(newEl) => newEl?.isEqualNode(oldEl ?? null)
)
if (matchedIndex !== -1) {
delete newElements[matchedIndex]
} else {
oldEl?.remove()
delete managedHeadElements[oldIndex]
}
})
newElements.forEach((el) => el && document.head.appendChild(el))
managedHeadElements = [...managedHeadElements, ...newElements].filter(
Boolean
)
}
watchEffect(() => {
@ -35,14 +47,19 @@ export function useUpdateHead(route: Route, siteDataByRouteRef: Ref<SiteData>) {
const frontmatterHead = (pageData && pageData.frontmatter.head) || []
// update title and description
document.title = createTitle(siteData, pageData)
const title = createTitle(siteData, pageData)
if (title !== document.title) {
document.title = title
}
const description = pageDescription || siteData.description
let metaDescriptionElement = document.querySelector(
`meta[name=description]`
)
if (metaDescriptionElement) {
metaDescriptionElement.setAttribute('content', description)
if (metaDescriptionElement.getAttribute('content') !== description) {
metaDescriptionElement.setAttribute('content', description)
}
} else {
createHeadElement(['meta', { name: 'description', content: description }])
}
@ -61,6 +78,10 @@ function createHeadElement([tag, attrs, innerHTML]: HeadConfig) {
if (innerHTML) {
el.innerHTML = innerHTML
}
if (tag === 'script' && !attrs.async) {
// async is true by default for dynamically created scripts
;(el as HTMLScriptElement).async = false
}
return el
}

@ -1,20 +1,22 @@
import siteData from '@siteData'
import { useDark } from '@vueuse/core'
import {
type InjectionKey,
type Ref,
computed,
inject,
readonly,
ref,
shallowRef
shallowRef,
type InjectionKey,
type Ref
} from 'vue'
import type { Route } from './router'
import siteData from '@siteData'
import {
type PageData,
type SiteData,
APPEARANCE_KEY,
createTitle,
resolveSiteDataByRoute,
createTitle
type PageData,
type SiteData
} from '../shared'
import type { Route } from './router'
export const dataSymbol: InjectionKey<VitePressData> = Symbol()
@ -67,6 +69,19 @@ export function initData(route: Route): VitePressData {
resolveSiteDataByRoute(siteDataRef.value, route.data.relativePath)
)
const appearance = site.value.appearance // fine with reactivity being lost here, config change triggers a restart
const isDark =
appearance === 'force-dark'
? ref(true)
: appearance
? useDark({
storageKey: APPEARANCE_KEY,
initialValue: () =>
typeof appearance === 'string' ? appearance : 'auto',
...(typeof appearance === 'object' ? appearance : {})
})
: ref(false)
return {
site,
theme: computed(() => site.value.themeConfig),
@ -82,7 +97,7 @@ export function initData(route: Route): VitePressData {
description: computed(() => {
return route.data.description || site.value.description
}),
isDark: ref(false)
isDark
}
}

@ -121,25 +121,28 @@ function newRouter(): Router {
return createRouter((path) => {
let pageFilePath = pathToFile(path)
let pageModule = null
if (!pageFilePath) return null
if (pageFilePath) {
if (isInitialPageLoad) {
initialPath = pageFilePath
}
if (isInitialPageLoad) {
initialPath = pageFilePath
}
// use lean build if this is the initial page load or navigating back
// to the initial loaded path (the static vnodes already adopted the
// static content on that load so no need to re-fetch the page)
if (isInitialPageLoad || initialPath === pageFilePath) {
pageFilePath = pageFilePath.replace(/\.js$/, '.lean.js')
}
// use lean build if this is the initial page load or navigating back
// to the initial loaded path (the static vnodes already adopted the
// static content on that load so no need to re-fetch the page)
if (isInitialPageLoad || initialPath === pageFilePath) {
pageFilePath = pageFilePath.replace(/\.js$/, '.lean.js')
pageModule = import(/*@vite-ignore*/ pageFilePath)
}
if (inBrowser) {
isInitialPageLoad = false
}
return import(/*@vite-ignore*/ pageFilePath)
return pageModule
}, Theme.NotFound)
}

@ -64,21 +64,9 @@ export function createRouter(
}
async function go(href: string = inBrowser ? location.href : '/') {
href = normalizeHref(href)
if ((await router.onBeforeRouteChange?.(href)) === false) return
const url = new URL(href, fakeHost)
if (!siteDataRef.value.cleanUrls) {
// ensure correct deep link so page refresh lands on correct files.
// if cleanUrls is enabled, the server should handle this
if (!url.pathname.endsWith('/') && !url.pathname.endsWith('.html')) {
url.pathname += '.html'
href = url.pathname + url.search + url.hash
}
}
if (inBrowser && href !== location.href) {
// save scroll position before changing url
history.replaceState({ scrollPosition: window.scrollY }, document.title)
history.pushState(null, '', href)
}
updateHistory(href)
await loadPage(href)
await router.onAfterRouteChanged?.(href)
}
@ -211,15 +199,18 @@ export function createRouter(
search === currentUrl.search
) {
// scroll between hash anchors in the same page
// avoid duplicate history entries when the hash is same
if (hash !== currentUrl.hash) {
history.pushState(null, '', hash)
// still emit the event so we can listen to it in themes
window.dispatchEvent(new Event('hashchange'))
}
if (hash) {
// avoid duplicate history entries when the hash is same
if (hash !== currentUrl.hash) {
history.pushState(null, '', hash)
// still emit the event so we can listen to it in themes
window.dispatchEvent(new Event('hashchange'))
}
// use smooth scroll when clicking on header anchor links
scrollTo(link, hash, link.classList.contains('header-anchor'))
} else {
updateHistory(href)
window.scrollTo(0, 0)
}
} else {
go(href)
@ -231,7 +222,10 @@ export function createRouter(
)
window.addEventListener('popstate', (e) => {
loadPage(location.href, (e.state && e.state.scrollPosition) || 0)
loadPage(
normalizeHref(location.href),
(e.state && e.state.scrollPosition) || 0
)
})
window.addEventListener('hashchange', (e) => {
@ -268,15 +262,20 @@ export function scrollTo(el: Element, hash: string, smooth = false) {
}
if (target) {
const scrollOffset = siteDataRef.value.scrollOffset
let offset: number = 0
let scrollOffset = siteDataRef.value.scrollOffset
let offset = 0
let padding = 24
if (typeof scrollOffset === 'object' && 'padding' in scrollOffset) {
padding = scrollOffset.padding
scrollOffset = scrollOffset.selector
}
if (typeof scrollOffset === 'number') {
offset = scrollOffset
} else if (typeof scrollOffset === 'string') {
offset = tryOffsetSelector(scrollOffset)
offset = tryOffsetSelector(scrollOffset, padding)
} else if (Array.isArray(scrollOffset)) {
for (const selector of scrollOffset) {
const res = tryOffsetSelector(selector)
const res = tryOffsetSelector(selector, padding)
if (res) {
offset = res
break
@ -292,31 +291,22 @@ export function scrollTo(el: Element, hash: string, smooth = false) {
target.getBoundingClientRect().top -
offset +
targetPadding
// only smooth scroll if distance is smaller than screen height.
function scrollToTarget() {
if (
!smooth ||
Math.abs(targetTop - window.scrollY) > window.innerHeight
) {
// only smooth scroll if distance is smaller than screen height.
if (!smooth || Math.abs(targetTop - window.scrollY) > window.innerHeight)
window.scrollTo(0, targetTop)
} else {
window.scrollTo({
left: 0,
top: targetTop,
behavior: 'smooth'
})
}
else window.scrollTo({ left: 0, top: targetTop, behavior: 'smooth' })
}
requestAnimationFrame(scrollToTarget)
}
}
function tryOffsetSelector(selector: string): number {
function tryOffsetSelector(selector: string, padding: number): number {
const el = document.querySelector(selector)
if (!el) return 0
const bot = el.getBoundingClientRect().bottom
if (bot < 0) return 0
return bot + 24
return bot + padding
}
function handleHMR(route: Route): void {
@ -332,9 +322,28 @@ function handleHMR(route: Route): void {
}
function shouldHotReload(payload: PageDataPayload): boolean {
const payloadPath = payload.path.replace(/(\bindex)?\.md$/, '')
const payloadPath = payload.path.replace(/(?:(^|\/)index)?\.md$/, '$1')
const locationPath = location.pathname
.replace(/(\bindex)?\.html$/, '')
.replace(/(?:(^|\/)index)?\.html$/, '')
.slice(siteDataRef.value.base.length - 1)
return payloadPath === locationPath
}
function updateHistory(href: string) {
if (inBrowser && href !== normalizeHref(location.href)) {
// save scroll position before changing url
history.replaceState({ scrollPosition: window.scrollY }, document.title)
history.pushState(null, '', href)
}
}
function normalizeHref(href: string): string {
const url = new URL(href, fakeHost)
url.pathname = url.pathname.replace(/(^|\/)index(\.html)?$/, '$1')
// ensure correct deep link so page refresh lands on correct files.
if (siteDataRef.value.cleanUrls)
url.pathname = url.pathname.replace(/\.html$/, '')
else if (!url.pathname.endsWith('/') && !url.pathname.endsWith('.html'))
url.pathname += '.html'
return url.pathname + url.search + url.hash
}

@ -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)
}

@ -1,5 +1,5 @@
// exports in this file are exposed to themes and md files via 'vitepress'
// so the user can do `import { useRoute, useSiteData } from 'vitepress'`
// so the user can do `import { useRoute, useData } from 'vitepress'`
// generic types
export type { VitePressData } from './app/data'

@ -29,7 +29,7 @@ declare module '@localSearchIndex' {
}
declare module 'mark.js/src/vanilla.js' {
import type { Mark } from 'mark.js'
const mark: Mark
import type Mark from 'mark.js'
const mark: typeof Mark
export default mark
}

@ -22,9 +22,6 @@ watch(() => route.path, closeSidebar)
useCloseSidebarOnEscape(isSidebarOpen, closeSidebar)
provide('close-sidebar', closeSidebar)
provide('is-sidebar-open', isSidebarOpen)
const { frontmatter } = useData()
const slots = useSlots()
@ -38,7 +35,7 @@ provide('hero-image-slot-exists', heroImageSlotExists)
<slot name="layout-top" />
<VPSkipLink />
<VPBackdrop class="backdrop" :show="isSidebarOpen" @click="closeSidebar" />
<VPNav v-if="frontmatter.navbar !== false">
<VPNav>
<template #nav-bar-title-before><slot name="nav-bar-title-before" /></template>
<template #nav-bar-title-after><slot name="nav-bar-title-after" /></template>
<template #nav-bar-content-before><slot name="nav-bar-content-before" /></template>

@ -91,19 +91,19 @@ onMounted(() => {
.link {
display: inline-block;
border: 1px solid var(--vp-c-brand);
border: 1px solid var(--vp-c-brand-1);
border-radius: 16px;
padding: 3px 16px;
font-size: 14px;
font-weight: 500;
color: var(--vp-c-brand);
color: var(--vp-c-brand-1);
transition:
border-color 0.25s,
color 0.25s;
}
.link:hover {
border-color: var(--vp-c-brand-dark);
color: var(--vp-c-brand-dark);
border-color: var(--vp-c-brand-2);
color: var(--vp-c-brand-2);
}
</style>

@ -1,8 +1,8 @@
<script setup lang="ts">
import type { DefaultTheme } from 'vitepress/theme'
import docsearch from '@docsearch/js'
import { onMounted, watch } from 'vue'
import { useRouter, useRoute } from 'vitepress'
import { useRoute, useRouter } from 'vitepress'
import type { DefaultTheme } from 'vitepress/theme'
import { nextTick, onMounted, watch } from 'vue'
import { useData } from '../composables/data'
const props = defineProps<{
@ -18,7 +18,8 @@ type DocSearchProps = Parameters<typeof docsearch>[0]
onMounted(update)
watch(localeIndex, update)
function update() {
async function update() {
await nextTick()
const options = {
...props.algolia,
...props.algolia.locales?.[localeIndex.value]
@ -84,14 +85,9 @@ function initialize(userOptions: DefaultTheme.AlgoliaSearchOptions) {
docsearch(options)
}
function getRelativePath(absoluteUrl: string) {
const { pathname, hash } = new URL(absoluteUrl)
return (
pathname.replace(
/\.html$/,
site.value.cleanUrls ? '' : '.html'
) + hash
)
function getRelativePath(url: string) {
const { pathname, hash } = new URL(url, location.origin)
return pathname.replace(/\.html$/, site.value.cleanUrls ? '' : '.html') + hash
}
</script>

@ -1,12 +1,15 @@
<script setup lang="ts">
defineProps<{
interface Props {
text?: string
type?: 'info' | 'tip' | 'warning' | 'danger'
}>()
}
withDefaults(defineProps<Props>(), {
type: 'tip'
})
</script>
<template>
<span class="VPBadge" :class="type ?? 'tip'">
<span class="VPBadge" :class="type">
<slot>{{ text }}</slot>
</span>
</template>
@ -16,26 +19,34 @@ defineProps<{
display: inline-block;
margin-left: 2px;
border: 1px solid transparent;
border-radius: 10px;
padding: 0 8px;
line-height: 18px;
border-radius: 12px;
padding: 0 10px;
line-height: 22px;
font-size: 12px;
font-weight: 600;
font-weight: 500;
transform: translateY(-2px);
}
h1 .VPBadge,
h2 .VPBadge,
h3 .VPBadge,
h4 .VPBadge,
h5 .VPBadge,
h6 .VPBadge {
vertical-align: text-top;
.vp-doc h1 > .VPBadge {
margin-top: 4px;
vertical-align: top;
}
h2 .VPBadge {
border-radius: 11px;
line-height: 20px;
.vp-doc h2 > .VPBadge {
margin-top: 3px;
padding: 0 8px;
vertical-align: top;
}
.vp-doc h3 > .VPBadge {
vertical-align: middle;
}
.vp-doc h4 > .VPBadge,
.vp-doc h5 > .VPBadge,
.vp-doc h6 > .VPBadge {
vertical-align: middle;
line-height: 18px;
}
.VPBadge.info {

@ -3,27 +3,24 @@ import { computed } from 'vue'
import { normalizeLink } from '../support/utils'
import { EXTERNAL_URL_RE } from '../../shared'
const props = defineProps<{
interface Props {
tag?: string
size?: 'medium' | 'big'
theme?: 'brand' | 'alt' | 'sponsor'
text: string
href?: string
}>()
const classes = computed(() => [
props.size ?? 'medium',
props.theme ?? 'brand'
])
}
const props = withDefaults(defineProps<Props>(), {
size: 'medium',
theme: 'brand'
})
const isExternal = computed(() => props.href && EXTERNAL_URL_RE.test(props.href))
const isExternal = computed(
() => props.href && EXTERNAL_URL_RE.test(props.href)
)
const component = computed(() => {
if (props.tag) {
return props.tag
}
return props.href ? 'a' : 'button'
return props.tag || props.href ? 'a' : 'button'
})
</script>
@ -31,7 +28,7 @@ const component = computed(() => {
<component
:is="component"
class="VPButton"
:class="classes"
:class="[size, theme]"
:href="href ? normalizeLink(href) : undefined"
:target="isExternal ? '_blank' : undefined"
:rel="isExternal ? 'noreferrer' : undefined"

@ -98,4 +98,12 @@ if (carbonOptions) {
.VPCarbonAds :deep(.carbon-poweredby:hover) {
color: var(--vp-carbon-ads-hover-poweredby-color);
}
.VPCarbonAds :deep(> div) {
display: none;
}
.VPCarbonAds :deep(> div:first-of-type) {
display: block;
}
</style>

@ -35,6 +35,11 @@ const { hasSidebar } = useSidebar()
<template #home-features-after><slot name="home-features-after" /></template>
</VPHome>
<component
v-else-if="frontmatter.layout && frontmatter.layout !== 'doc'"
:is="frontmatter.layout"
/>
<VPDoc v-else>
<template #doc-top><slot name="doc-top" /></template>
<template #doc-bottom><slot name="doc-bottom" /></template>

@ -1,4 +1,5 @@
<script setup lang="ts">
import { onContentUpdated } from 'vitepress'
import { ref, shallowRef } from 'vue'
import { useData } from '../composables/data'
import {
@ -8,16 +9,13 @@ import {
type MenuItem
} from '../composables/outline'
import VPDocOutlineItem from './VPDocOutlineItem.vue'
import { onContentUpdated } from 'vitepress'
const { frontmatter, theme } = useData()
const headers = shallowRef<MenuItem[]>([])
onContentUpdated(() => {
headers.value = getHeaders(
frontmatter.value.outline ?? theme.value.outline
)
headers.value = getHeaders(frontmatter.value.outline ?? theme.value.outline)
})
const container = ref()
@ -27,11 +25,16 @@ useActiveAnchor(container, marker)
</script>
<template>
<div class="VPDocAsideOutline" :class="{ 'has-outline': headers.length > 0 }" ref="container">
<div
class="VPDocAsideOutline"
:class="{ 'has-outline': headers.length > 0 }"
ref="container"
role="navigation"
>
<div class="content">
<div class="outline-marker" ref="marker" />
<div class="outline-title">{{ resolveTitle(theme) }}</div>
<div class="outline-title" role="heading" aria-level="2">{{ resolveTitle(theme) }}</div>
<nav aria-labelledby="doc-outline-aria-label">
<span class="visually-hidden" id="doc-outline-aria-label">
@ -66,10 +69,14 @@ useActiveAnchor(container, marker)
left: -1px;
z-index: 0;
opacity: 0;
width: 1px;
width: 2px;
border-radius: 2px;
height: 18px;
background-color: var(--vp-c-brand);
transition: top 0.25s cubic-bezier(0, 1, 0.5, 1), background-color 0.5s, opacity 0.25s;
background-color: var(--vp-c-brand-1);
transition:
top 0.25s cubic-bezier(0, 1, 0.5, 1),
background-color 0.5s,
opacity 0.25s;
}
.outline-title {

@ -83,12 +83,12 @@ const showFooter = computed(() => {
line-height: 32px;
font-size: 14px;
font-weight: 500;
color: var(--vp-c-brand);
color: var(--vp-c-brand-1);
transition: color 0.25s;
}
.edit-link-button:hover {
color: var(--vp-c-brand-dark);
color: var(--vp-c-brand-2);
}
.edit-link-icon {
@ -123,7 +123,7 @@ const showFooter = computed(() => {
}
.pager-link:hover {
border-color: var(--vp-c-brand);
border-color: var(--vp-c-brand-1);
}
.pager-link.next {
@ -144,7 +144,7 @@ const showFooter = computed(() => {
line-height: 20px;
font-size: 14px;
font-weight: 500;
color: var(--vp-c-brand);
color: var(--vp-c-brand-1);
transition: color 0.25s;
}
</style>

@ -2,9 +2,11 @@
import { ref, computed, watchEffect, onMounted } from 'vue'
import { useData } from '../composables/data'
const { theme, page } = useData()
const { theme, page, frontmatter, lang } = useData()
const date = computed(() => new Date(page.value.lastUpdated!))
const date = computed(
() => new Date(frontmatter.value.lastUpdated ?? page.value.lastUpdated)
)
const isoDatetime = computed(() => date.value.toISOString())
const datetime = ref('')
@ -13,7 +15,7 @@ const datetime = ref('')
onMounted(() => {
watchEffect(() => {
datetime.value = new Intl.DateTimeFormat(
undefined,
theme.value.lastUpdated?.formatOptions?.forceLocale ? lang.value : undefined,
theme.value.lastUpdated?.formatOptions ?? {
dateStyle: 'short',
timeStyle: 'short'

@ -36,7 +36,7 @@ onContentUpdated(() => {
<style scoped>
.VPDocOutlineDropdown {
margin-bottom: 42px;
margin-bottom: 48px;
}
.VPDocOutlineDropdown button {
@ -44,11 +44,12 @@ onContentUpdated(() => {
font-size: 14px;
font-weight: 500;
line-height: 24px;
color: var(--vp-c-text-2);
transition: color 0.5s;
border: 1px solid var(--vp-c-border);
padding: 4px 12px;
color: var(--vp-c-text-2);
background-color: var(--vp-c-default-soft);
border-radius: 8px;
transition: color 0.5s;
}
.VPDocOutlineDropdown button:hover {
@ -63,14 +64,14 @@ onContentUpdated(() => {
.icon {
display: inline-block;
vertical-align: middle;
margin-left: 2px;
width: 14px;
height: 14px;
width: 16px;
height: 16px;
fill: currentColor;
}
:deep(.outline-link) {
font-size: 13px;
font-size: 14px;
font-weight: 400;
}
.open > .icon {
@ -78,7 +79,7 @@ onContentUpdated(() => {
}
.items {
margin-top: 10px;
margin-top: 12px;
border-left: 1px solid var(--vp-c-divider);
}
</style>

@ -9,7 +9,7 @@ defineProps<{
function onClick({ target: el }: Event) {
const id = (el as HTMLAnchorElement).href!.split('#')[1]
const heading = document.getElementById(decodeURIComponent(id))
heading?.focus()
heading?.focus({ preventScroll: true })
}
</script>
@ -31,7 +31,7 @@ function onClick({ target: el }: Event) {
}
.nested {
padding-left: 13px;
padding-left: 16px;
}
.outline-link {
@ -42,7 +42,7 @@ function onClick({ target: el }: Event) {
overflow: hidden;
text-overflow: ellipsis;
transition: color 0.5s;
font-weight: 500;
font-weight: 400;
}
.outline-link:hover,

@ -11,18 +11,34 @@ defineProps<{
link?: string
linkText?: string
rel?: string
target?: string
}>()
</script>
<template>
<VPLink class="VPFeature" :href="link" :rel="rel" :no-icon="true" :tag="link ? 'a' : 'div'">
<VPLink
class="VPFeature"
:href="link"
:rel="rel"
:target="target"
:no-icon="true"
:tag="link ? 'a' : 'div'"
>
<article class="box">
<div v-if="typeof icon === 'object' && icon.wrap" class="icon">
<VPImage
:image="icon"
:alt="icon.alt"
:height="icon.height || 48"
:width="icon.width || 48"
/>
</div>
<VPImage
v-if="typeof icon === 'object'"
v-else-if="typeof icon === 'object'"
:image="icon"
:alt="icon.alt"
:height="icon.height"
:width="icon.width"
:height="icon.height || 48"
:width="icon.width || 48"
/>
<div v-else-if="icon" class="icon" v-html="icon"></div>
<h2 class="title" v-html="title"></h2>
@ -48,8 +64,7 @@ defineProps<{
}
.VPFeature.link:hover {
border-color: var(--vp-c-brand);
background-color: var(--vp-c-bg-soft-up);
border-color: var(--vp-c-brand-1);
}
.box {
@ -59,9 +74,7 @@ defineProps<{
height: 100%;
}
.VPFeature:deep(.VPImage) {
width: 48px;
height: 48px;
.box > :deep(.VPImage) {
margin-bottom: 20px;
}
@ -71,7 +84,7 @@ defineProps<{
align-items: center;
margin-bottom: 20px;
border-radius: 6px;
background-color: var(--vp-c-bg-soft-down);
background-color: var(--vp-c-default-soft);
width: 48px;
height: 48px;
font-size: 24px;
@ -102,7 +115,7 @@ defineProps<{
align-items: center;
font-size: 14px;
font-weight: 500;
color: var(--vp-c-brand);
color: var(--vp-c-brand-1);
}
.link-text-icon {

@ -10,6 +10,7 @@ export interface Feature {
link?: string
linkText?: string
rel?: string
target?: string
}
const props = defineProps<{
@ -50,6 +51,7 @@ const grid = computed(() => {
:link="feature.link"
:link-text="feature.linkText"
:rel="feature.rel"
:target="feature.target"
/>
</div>
</div>

@ -39,7 +39,7 @@ function onBlur() {
>
<span v-if="button || icon" class="text">
<component v-if="icon" :is="icon" class="option-icon" />
{{ button }}
<span v-if="button" v-html="button"></span>
<VPIconChevronDown class="text-icon" />
</span>
@ -60,7 +60,7 @@ function onBlur() {
}
.VPFlyout:hover {
color: var(--vp-c-brand);
color: var(--vp-c-brand-1);
transition: color 0.25s;
}
@ -73,11 +73,11 @@ function onBlur() {
}
.VPFlyout.active .text {
color: var(--vp-c-brand);
color: var(--vp-c-brand-1);
}
.VPFlyout.active:hover .text {
color: var(--vp-c-brand-dark);
color: var(--vp-c-brand-2);
}
.VPFlyout:hover .menu,
@ -87,6 +87,12 @@ function onBlur() {
transform: translateY(0);
}
.button[aria-expanded="false"] + .menu {
opacity: 0;
visibility: hidden;
transform: translateY(0);
}
.button {
display: flex;
align-items: center;

@ -14,13 +14,16 @@ export interface Sponsor {
img: string
url: string
}
defineProps<{
interface Props {
message?: string
actionText?: string
actionLink?: string
data: Sponsors[]
}>()
}
withDefaults(defineProps<Props>(), {
actionText: 'Become a sponsor'
})
</script>
<template>
@ -36,11 +39,7 @@ defineProps<{
</div>
<div v-if="actionLink" class="action">
<VPButton
theme="sponsor"
:text="actionText ?? 'Become a sponsor'"
:href="actionLink"
/>
<VPButton theme="sponsor" :text="actionText" :href="actionLink" />
</div>
</div>
</section>

@ -6,12 +6,8 @@ defineProps<{
image: DefaultTheme.ThemeableImage
alt?: string
}>()
</script>
<script lang="ts">
export default {
inheritAttrs: false
}
defineOptions({ inheritAttrs: false })
</script>
<template>

@ -1,10 +1,10 @@
<script lang="ts" setup>
import { useWindowScroll } from '@vueuse/core'
import { onContentUpdated } from 'vitepress'
import { computed, shallowRef, ref, onMounted } from 'vue'
import { computed, onMounted, ref, shallowRef } from 'vue'
import { useData } from '../composables/data'
import { useSidebar } from '../composables/sidebar'
import { getHeaders, type MenuItem } from '../composables/outline'
import { useSidebar } from '../composables/sidebar'
import VPLocalNavOutlineDropdown from './VPLocalNavOutlineDropdown.vue'
import VPIconAlignLeft from './icons/VPIconAlignLeft.vue'
@ -18,6 +18,7 @@ defineEmits<{
const { theme, frontmatter } = useData()
const { hasSidebar } = useSidebar()
// @ts-ignore
const { y } = useWindowScroll()
const headers = shallowRef<MenuItem[]>([])

@ -58,10 +58,14 @@ function scrollToTop() {
class="items"
@click="onItemClick"
>
<a class="top-link" href="#" @click="scrollToTop">
{{ theme.returnToTopLabel || 'Return to top' }}
</a>
<VPDocOutlineItem :headers="headers" />
<div class="header">
<a class="top-link" href="#" @click="scrollToTop">
{{ theme.returnToTopLabel || 'Return to top' }}
</a>
</div>
<div class="outline">
<VPDocOutlineItem :headers="headers" />
</div>
</div>
</Transition>
</div>
@ -71,6 +75,7 @@ function scrollToTop() {
.VPLocalNavOutlineDropdown {
padding: 12px 20px 11px;
}
.VPLocalNavOutlineDropdown button {
display: block;
font-size: 12px;
@ -110,26 +115,35 @@ function scrollToTop() {
.items {
position: absolute;
left: 20px;
right: 20px;
top: 64px;
background-color: var(--vp-local-nav-bg-color);
padding: 4px 10px 16px;
border: 1px solid var(--vp-c-divider);
right: 16px;
left: 16px;
display: grid;
gap: 1px;
border: 1px solid var(--vp-c-border);
border-radius: 8px;
background-color: var(--vp-c-gutter);
max-height: calc(var(--vp-vh, 100vh) - 86px);
overflow: hidden auto;
box-shadow: var(--vp-shadow-3);
}
.header {
background-color: var(--vp-c-bg-soft);
}
.top-link {
display: block;
color: var(--vp-c-brand);
font-size: 13px;
padding: 0 16px;
line-height: 48px;
font-size: 14px;
font-weight: 500;
padding: 6px 0;
margin: 0 13px 10px;
border-bottom: 1px solid var(--vp-c-divider);
color: var(--vp-c-brand-1);
}
.outline {
padding: 8px 0;
background-color: var(--vp-c-bg-soft);
}
.flyout-enter-active {

@ -4,6 +4,7 @@ import {
computedAsync,
debouncedWatch,
onKeyStroke,
reactify,
useEventListener,
useLocalStorage,
useScrollLock,
@ -12,7 +13,7 @@ import {
import { useFocusTrap } from '@vueuse/integrations/useFocusTrap'
import Mark from 'mark.js/src/vanilla.js'
import MiniSearch, { type SearchResult } from 'minisearch'
import { useRouter, dataSymbol } from 'vitepress'
import { dataSymbol, inBrowser, useRouter } from 'vitepress'
import {
computed,
createApp,
@ -22,6 +23,7 @@ import {
onMounted,
ref,
shallowRef,
toRef,
watch,
watchEffect,
type Ref
@ -31,17 +33,12 @@ import { pathToFile } from '../../app/utils'
import { useData } from '../composables/data'
import { createTranslate } from '../support/translation'
defineProps<{
placeholder: string
}>()
const emit = defineEmits<{
(e: 'close'): void
}>()
const el = shallowRef<HTMLElement>()
const resultsEl = shallowRef<HTMLElement>()
const body = shallowRef<HTMLElement>()
/* Search */
@ -116,6 +113,16 @@ const disableDetailedView = computed(() => {
)
})
const buttonText = computed(() => {
const options = theme.value.search?.options ?? theme.value.algolia
return (
options?.locales?.[localeIndex.value]?.translations?.button?.buttonText ||
options?.translations?.button?.buttonText ||
'Search'
)
})
watchEffect(() => {
if (disableDetailedView.value) {
showDetailedList.value = false
@ -308,8 +315,16 @@ onKeyStroke('ArrowDown', (event) => {
const router = useRouter()
onKeyStroke('Enter', () => {
onKeyStroke('Enter', (e) => {
if (e.target instanceof HTMLButtonElement && e.target.type !== 'submit')
return
const selectedPackage = results.value[selectedIndex.value]
if (e.target instanceof HTMLInputElement && !selectedPackage) {
e.preventDefault()
return
}
if (selectedPackage) {
router.go(selectedPackage.id)
emit('close')
@ -339,7 +354,10 @@ const defaultTranslations: { modal: ModalTranslations } = {
}
}
const $t = createTranslate(theme.value.search?.options, defaultTranslations)
const $t = reactify(createTranslate)(
toRef(() => theme.value.search?.options),
defaultTranslations
)
// Back
@ -354,10 +372,9 @@ useEventListener('popstate', (event) => {
})
/** Lock body */
const isLocked = useScrollLock(body)
const isLocked = useScrollLock(inBrowser ? document.body : null)
onMounted(() => {
body.value = document.body
nextTick(() => {
isLocked.value = true
nextTick().then(() => activate())
@ -408,7 +425,7 @@ function formMarkRegex(terms: Set<string>) {
@submit.prevent=""
>
<label
:title="placeholder"
:title="buttonText"
id="localsearch-label"
for="localsearch-input"
>
@ -457,7 +474,7 @@ function formMarkRegex(terms: Set<string>) {
<input
ref="searchInput"
v-model="filterText"
:placeholder="placeholder"
:placeholder="buttonText"
id="localsearch-input"
aria-labelledby="localsearch-label"
class="search-input"
@ -466,6 +483,7 @@ function formMarkRegex(terms: Set<string>) {
<button
v-if="!disableDetailedView"
class="toggle-layout-button"
type="button"
:class="{ 'detailed-list': showDetailedList }"
:title="$t('modal.displayDetails')"
@click="
@ -668,7 +686,7 @@ function formMarkRegex(terms: Set<string>) {
border-radius: 6px;
}
@media (max-width: 768px) {
@media (max-width: 767px) {
.shell {
margin: 0;
width: 100vw;
@ -687,21 +705,21 @@ function formMarkRegex(terms: Set<string>) {
cursor: text;
}
@media (max-width: 768px) {
@media (max-width: 767px) {
.search-bar {
padding: 0 8px;
}
}
.search-bar:focus-within {
border-color: var(--vp-c-brand);
border-color: var(--vp-c-brand-1);
}
.search-icon {
margin: 8px;
}
@media (max-width: 768px) {
@media (max-width: 767px) {
.search-icon {
display: none;
}
@ -713,7 +731,7 @@ function formMarkRegex(terms: Set<string>) {
width: 100%;
}
@media (max-width: 768px) {
@media (max-width: 767px) {
.search-input {
padding: 6px 4px;
}
@ -742,7 +760,7 @@ function formMarkRegex(terms: Set<string>) {
.search-actions button:not([disabled]):hover,
.toggle-layout-button.detailed-list {
color: var(--vp-c-brand);
color: var(--vp-c-brand-1);
}
.search-actions button.clear-button:disabled {
@ -764,7 +782,7 @@ function formMarkRegex(terms: Set<string>) {
gap: 4px;
}
@media (max-width: 768px) {
@media (max-width: 767px) {
.search-keyboard-shortcuts {
display: none;
}
@ -808,7 +826,7 @@ function formMarkRegex(terms: Set<string>) {
overflow: hidden;
}
@media (max-width: 768px) {
@media (max-width: 767px) {
.result > div {
margin: 8px;
}
@ -836,7 +854,7 @@ function formMarkRegex(terms: Set<string>) {
.title-icon {
opacity: 0.5;
font-weight: 500;
color: var(--vp-c-brand);
color: var(--vp-c-brand-1);
}
.title svg {
@ -909,7 +927,7 @@ function formMarkRegex(terms: Set<string>) {
.result.selected .titles,
.result.selected .title-icon {
color: var(--vp-c-brand) !important;
color: var(--vp-c-brand-1) !important;
}
.no-results {

@ -44,11 +44,11 @@ const { page } = useData()
}
.link:hover {
color: var(--vp-c-brand);
background-color: var(--vp-c-bg-elv-mute);
color: var(--vp-c-brand-1);
background-color: var(--vp-c-default-soft);
}
.link.active {
color: var(--vp-c-brand);
color: var(--vp-c-brand-1);
}
</style>

@ -1,16 +1,29 @@
<script setup lang="ts">
import { provide } from 'vue'
import { inBrowser } from 'vitepress'
import { computed, provide, watchEffect } from 'vue'
import { useData } from '../composables/data'
import { useNav } from '../composables/nav'
import VPNavBar from './VPNavBar.vue'
import VPNavScreen from './VPNavScreen.vue'
const { isScreenOpen, closeScreen, toggleScreen } = useNav()
const { frontmatter } = useData()
const hasNavbar = computed(() => {
return frontmatter.value.navbar !== false
})
provide('close-screen', closeScreen)
watchEffect(() => {
if (inBrowser) {
document.documentElement.classList.toggle('hide-nav', !hasNavbar.value)
}
})
</script>
<template>
<header class="VPNav">
<header v-if="hasNavbar" class="VPNav">
<VPNavBar :is-screen-open="isScreenOpen" @toggle-screen="toggleScreen">
<template #nav-bar-title-before><slot name="nav-bar-title-before" /></template>
<template #nav-bar-title-after><slot name="nav-bar-title-after" /></template>

@ -1,6 +1,7 @@
<script lang="ts" setup>
import { useWindowScroll } from '@vueuse/core'
import { computed } from 'vue'
import { ref, watchPostEffect } from 'vue'
import { useData } from '../composables/data'
import { useSidebar } from '../composables/sidebar'
import VPNavBarAppearance from './VPNavBarAppearance.vue'
import VPNavBarExtra from './VPNavBarExtra.vue'
@ -19,13 +20,19 @@ defineEmits<{
(e: 'toggle-screen'): void
}>()
// @ts-ignore
const { y } = useWindowScroll()
const { hasSidebar } = useSidebar()
const { frontmatter } = useData()
const classes = computed(() => ({
'has-sidebar': hasSidebar.value,
fill: y.value > 0
}))
const classes = ref<Record<string, boolean>>({})
watchPostEffect(() => {
classes.value = {
'has-sidebar': hasSidebar.value,
top: frontmatter.value.layout === 'home' && y.value === 0,
}
})
</script>
<template>
@ -77,7 +84,7 @@ const classes = computed(() => ({
padding: 0;
}
.VPNavBar.fill:not(.has-sidebar) {
.VPNavBar:not(.has-sidebar):not(.top) {
border-bottom-color: var(--vp-c-gutter);
background-color: var(--vp-nav-bg-color);
}
@ -162,14 +169,13 @@ const classes = computed(() => ({
}
@media (min-width: 960px) {
.VPNavBar.has-sidebar .content-body,
.VPNavBar.fill .content-body {
.VPNavBar:not(.top) .content-body{
position: relative;
background-color: var(--vp-nav-bg-color);
}
}
@media (max-width: 768px) {
@media (max-width: 767px) {
.content-body {
column-gap: 0.5rem;
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save