Merge remote-tracking branch 'origin/main' into chgeo-main

pull/4067/head
Divyansh Singh 11 months ago
commit 3de723a98a

@ -1,3 +1,22 @@
# [1.4.0](https://github.com/vuejs/vitepress/compare/v1.3.4...v1.4.0) (2024-10-07)
### Bug Fixes
- `vueRE` conflicting with `lineNoRE` ([#4247](https://github.com/vuejs/vitepress/issues/4247)) ([2ac64b8](https://github.com/vuejs/vitepress/commit/2ac64b8d4180f2a7c54fda57df7f3a0a52488d62))
- hmr not updating page data in rewritten paths and file path is wrong in mdit for dynamic routes ([c46e4b7](https://github.com/vuejs/vitepress/commit/c46e4b784ddb9ce3bd1cfcc3de1d1d676535cb5b)), closes [#4172](https://github.com/vuejs/vitepress/issues/4172)
- remove font synthesis in webfont mode, google fonts now support italic axis in inter ([1628918](https://github.com/vuejs/vitepress/commit/1628918f30b5602b83c51a2a8f4ec5e773cf7445))
- **theme:** change the order of CSS rules of `VPFlyout` ([#4225](https://github.com/vuejs/vitepress/issues/4225)) ([68150a6](https://github.com/vuejs/vitepress/commit/68150a6f3349c1741ed5683e3010d9ecea02f3a8)), closes [#4224](https://github.com/vuejs/vitepress/issues/4224)
- **theme:** respect custom tag prop in VPButton component ([#4185](https://github.com/vuejs/vitepress/issues/4185)) ([9c5d348](https://github.com/vuejs/vitepress/commit/9c5d348c034eb6773562c93cad699d287051aa7b))
### Features
- add `data-title` attribute for code group label tag ([#4152](https://github.com/vuejs/vitepress/issues/4152)) ([bc7271d](https://github.com/vuejs/vitepress/commit/bc7271d258047feb8a39c97ebc5e2a16bf899bb5))
- allow ignoring certain headers and their subtrees completely in outline ([3e11b6a](https://github.com/vuejs/vitepress/commit/3e11b6abf5fbe80c2bc733f590ab57c7b2cc06f2)), closes [#4171](https://github.com/vuejs/vitepress/issues/4171)
- **client:** add `onAfterPageLoad` hook in router ([#4126](https://github.com/vuejs/vitepress/issues/4126)) ([315c220](https://github.com/vuejs/vitepress/commit/315c22004993f6f1cbdbb59178e46745d8e505a6))
- support adding extra attributes to snippet imports (useful for twoslash) ([#4100](https://github.com/vuejs/vitepress/issues/4100)) ([e8f7dd1](https://github.com/vuejs/vitepress/commit/e8f7dd16f6139fdfd129b86caff4b6613dd1e887))
- **theme:** expose theme default VPLink & VPSocialLink(s) component ([#4178](https://github.com/vuejs/vitepress/issues/4178)) ([615e33b](https://github.com/vuejs/vitepress/commit/615e33bb24d5005574af971ffcf1f41d751a855c))
- trigger `onContentUpdated` on frontmatter-only changes too ([0db269a](https://github.com/vuejs/vitepress/commit/0db269a4c5d90ecf69f0219982cdf8f335e787ce))
## [1.3.4](https://github.com/vuejs/vitepress/compare/v1.3.3...v1.3.4) (2024-08-24)
### Bug Fixes

@ -60,7 +60,7 @@ export const shared = defineConfig({
provider: 'algolia',
options: {
appId: '8J64VVRP8K',
apiKey: 'a18e2f4cc5665f6602c5631fd868adfd',
apiKey: '52f578a92b88ad6abde815aae2b0ad7c',
indexName: 'vitepress',
locales: {
...zhSearch,

@ -156,22 +156,24 @@ You can customize the mapping between the source directory structure and the gen
```
.
─ packages
├─ pkg-a
│ └─ src
│ │ ├─ pkg-a-code.ts
│ │ └─ pkg-a-docs.md
└─ pkg-b
└─ src
│ ├─ pkg-b-code.ts
│ └─ pkg-b-docs.md
─ packages
├─ pkg-a
│ └─ src
│ ├─ foo.md
│ └─ index.md
└─ pkg-b
└─ src
├─ bar.md
└─ index.md
```
And you want the VitePress pages to be generated like this:
```
packages/pkg-a/src/pkg-a-docs.md --> /pkg-a/index.html
packages/pkg-b/src/pkg-b-docs.md --> /pkg-b/index.html
packages/pkg-a/src/index.md --> /pkg-a/index.html
packages/pkg-a/src/foo.md --> /pkg-a/foo.html
packages/pkg-b/src/index.md --> /pkg-b/index.html
packages/pkg-b/src/bar.md --> /pkg-b/bar.html
```
You can achieve this by configuring the [`rewrites`](../reference/site-config#rewrites) option like this:
@ -180,8 +182,10 @@ You can achieve this by configuring the [`rewrites`](../reference/site-config#re
// .vitepress/config.js
export default {
rewrites: {
'packages/pkg-a/src/pkg-a-docs.md': 'pkg-a/index.md',
'packages/pkg-b/src/pkg-b-docs.md': 'pkg-b/index.md'
'packages/pkg-a/src/index.md': 'pkg-a/index.md',
'packages/pkg-a/src/foo.md': 'pkg-a/foo.md',
'packages/pkg-b/src/index.md': 'pkg-b/index.md',
'packages/pkg-b/src/bar.md': 'pkg-b/bar.md'
}
}
```
@ -191,12 +195,22 @@ The `rewrites` option also supports dynamic route parameters. In the above examp
```ts
export default {
rewrites: {
'packages/:pkg/src/(.*)': ':pkg/index.md'
'packages/:pkg/src/:slug*': ':pkg/:slug*'
}
}
```
The rewrite paths are compiled using the `path-to-regexp` package - consult [its documentation](https://github.com/pillarjs/path-to-regexp#parameters) for more advanced syntax.
The rewrite paths are compiled using the `path-to-regexp` package - consult [its documentation](https://github.com/pillarjs/path-to-regexp/tree/6.x#parameters) for more advanced syntax.
`rewrites` can also be a function that receives the original path and returns the new path:
```ts
export default {
rewrites(id) {
return id.replace(/^packages\/([^/]+)\/src\//, '$1/')
}
}
```
::: warning Relative Links with Rewrites

@ -296,7 +296,7 @@ new Crawler({
lvl1: '.content h1',
content: '.content p, .content li',
lvl0: {
selectors: '',
selectors: 'section.has-active div h2',
defaultValue: 'Documentation'
},
lvl2: '.content h2',

@ -103,8 +103,8 @@ interface Router {
*/
onBeforeRouteChange?: (to: string) => Awaitable<void | boolean>
/**
* Called before the page component is loaded (after the history state is
* updated). Return `false` to cancel the navigation.
* Called before the page component is loaded (after the history state is updated).
* Return `false` to cancel the navigation.
*/
onBeforePageLoad?: (to: string) => Awaitable<void | boolean>
/**

@ -289,7 +289,7 @@ new Crawler({
lvl1: '.content h1',
content: '.content p, .content li',
lvl0: {
selectors: '',
selectors: 'section.has-active div h2',
defaultValue: 'Documentation'
},
lvl2: '.content h2',

@ -296,7 +296,7 @@ new Crawler({
lvl1: '.content h1',
content: '.content p, .content li',
lvl0: {
selectors: '',
selectors: 'section.has-active div h2',
defaultValue: 'Documentation'
},
lvl2: '.content h2',

@ -289,7 +289,7 @@ new Crawler({
lvl1: '.content h1',
content: '.content p, .content li',
lvl0: {
selectors: '',
selectors: 'section.has-active div h2',
defaultValue: 'Documentation'
},
lvl2: '.content h2',

@ -10,7 +10,7 @@
Вы можете ссылаться на статические ресурсы в ваших файлах разметки, компоненты `*.vue` в теме, стили и обычные файлы `.css`, используя абсолютные пути (основанные на корне проекта) или относительные пути (основанные на вашей файловой системе). Последнее похоже на поведение, к которому вы привыкли, если использовали Vite, Vue CLI или `file-loader` в webpack.
Распространенные типы файлов изображений, мультимедиа и шрифтов определяются и включаются в качестве ресурсов автоматически.
Распространённые типы файлов изображений, мультимедиа и шрифтов определяются и включаются в качестве ресурсов автоматически.
::: tip Связанные файлы не рассматриваются как ресурсы
PDF-файлы или другие документы, на которые есть ссылки в файлах с разметкой, не рассматриваются автоматически как ресурсы. Чтобы сделать связанные файлы доступными, вы должны вручную поместить их в каталог [`public`](#the-public-directory) вашего проекта.

@ -175,7 +175,7 @@ export default {
}
```
**Types**
**Типы**
```ts
interface ContentOptions<T = ContentData[]> {
@ -226,7 +226,7 @@ interface ContentOptions<T = ContentData[]> {
## Загрузчики типизированных данных {#typed-data-loaders}
При использовании TypeScript вы можете ввести свой загрузчик и экспортировать `data` следующим образом:
При использовании TypeScript можно ввести свой загрузчик и экспортировать `data` следующим образом:
```ts
import { defineLoader } from 'vitepress'

@ -4,7 +4,7 @@ outline: deep
# Развёртывание вашего сайта VitePress {#deploy-your-vitepress-site}
Следующие руководства основаны на некоторых общих предположениях:
Следующие инструкции основаны на некоторых общих предположениях:
- Сайт VitePress находится в директории `docs` вашего проекта.
- Вы используете выходной каталог сборки по умолчанию (`.vitepress/dist`).
@ -19,7 +19,7 @@ outline: deep
}
```
## Создание и локальное тестирование {#build-and-test-locally}
## Сборка и локальное тестирование {#build-and-test-locally}
1. Выполните эту команду, чтобы собрать документацию:
@ -33,9 +33,9 @@ outline: deep
$ npm run docs:preview
```
Команда `preview` загрузит локальный статический веб-сервер, который будет обслуживать выходной каталог `.vitepress/dist` по адресу `http://localhost:4173`. Вы можете использовать это, чтобы убедиться, что всё выглядит хорошо, прежде чем отправлять в производство.
Команда `preview` загрузит локальный статический веб-сервер, который будет обслуживать выходной каталог `.vitepress/dist` по адресу `http://localhost:4173`. Вы можете использовать его для теста, чтобы убедиться, что всё выглядит хорошо, прежде чем отправлять в производство.
3. Вы можете настроить порт сервера, передав `--port` в качестве аргумента.
3. Можно указать порт сервера, передав `--port` в качестве аргумента.
```json
{
@ -55,11 +55,11 @@ outline: deep
## Заголовки кэша HTTP {#http-cache-headers}
Если вы контролируете HTTP-заголовки на своем рабочем сервере, вы можете настроить заголовки `cache-control` для достижения лучшей производительности при повторных посещениях.
Если вы контролируете HTTP-заголовки на своем рабочем сервере, можно настроить заголовки `cache-control` для достижения лучшей производительности при повторных посещениях.
В производственной сборке используются хэшированные имена файлов для статических ресурсов (JavaScript, CSS и другие импортированные ресурсы, не находящиеся в `public`). Если вы просмотрите предварительную версию с помощью сетевой вкладки devtools вашего браузера, вы увидите файлы типа `app.4f283b18.js`.
В производственной сборке используются хэшированные имена файлов для статических ресурсов (JavaScript, CSS и другие импортированные ресурсы, не находящиеся в `public`). Если вы просмотрите предварительную версию с помощью вкладки «Network» («Сеть») инструментов разработчика вашего браузера, вы увидите файлы типа `app.4f283b18.js`.
Этот хэш `4f283b18` генерируется из содержимого этого файла. Один и тот же хэшированный URL гарантированно обслуживает одно и то же содержимое файла — если содержимое меняется, то и URL тоже. Это означает, что вы можете смело использовать самые сильные заголовки кэша для этих файлов. Все такие файлы будут помещены в каталог `assets/` в выходном каталоге, поэтому вы можете настроить для них следующий заголовок:
Этот хэш `4f283b18` генерируется из содержимого этого файла. Один и тот же хэшированный URL гарантированно обслуживает одно и то же содержимое файла — если содержимое меняется, то и URL тоже. Это означает, что можно смело использовать самые сильные настройки кэширования для этих файлов. Все такие файлы будут помещены в каталог `assets/` в выходном каталоге, поэтому вы можете настроить для них следующий заголовок:
```
Cache-Control: max-age=31536000,immutable
@ -198,7 +198,7 @@ Cache-Control: max-age=31536000,immutable
### GitLab Pages {#gitlab-pages}
1. Установите значение `../public` для параметра `outDir` в конфигурации VitePress. Настройте опцию `base` на `'/<репозиторий>/'`, если вы хотите развернуть ваш проект по адресу `https://<имя пользователя>.gitlab.io/<репозиторий>/`. Вам не нужна опция `base`, если вы выполняете развёртывание на личном домене, страницах пользователя или группы или если в GitLab включен параметр «Использовать уникальный домен».
1. Установите значение `../public` для параметра `outDir` в конфигурации VitePress. Настройте опцию `base` на `'/<репозиторий>/'`, если вы хотите развернуть ваш проект по адресу `https://<имя пользователя>.gitlab.io/<репозиторий>/`. Вам не нужна опция `base`, если вы выполняете развёртывание на личном домене, страницах пользователя или группы, или если в GitLab включен параметр «Использовать уникальный домен».
2. Создайте файл с именем `.gitlab-ci.yml` в корне вашего проекта с приведённым ниже содержимым. Это позволит создавать и развёртывать ваш сайт каждый раз, когда вы вносите изменения в его содержимое:

@ -4,7 +4,7 @@ outline: deep
# Расширение темы по умолчанию {#extending-the-default-theme}
Тема VitePress по умолчанию оптимизирована для документации и может быть настроена по своему усмотрению. Полный список опций можно найти в главе [Настройки темы по умолчанию](../reference/default-theme-config).
Тема VitePress по умолчанию оптимизирована для документации и может быть настроена по вашему усмотрению. Полный список опций можно найти в главе [Настройки темы по умолчанию](../reference/default-theme-config).
Однако есть ряд случаев, когда одной лишь конфигурации будет недостаточно. Например:
@ -12,7 +12,7 @@ outline: deep
2. Вам нужно изменить экземпляр приложения Vue, например, чтобы зарегистрировать глобальные компоненты;
3. Вам нужно внедрить пользовательский контент в тему через слоты макета.
Эти расширенные настройки потребуют использования пользовательской темы, которая «расширяет» тема по умолчанию.
Эти расширенные настройки потребуют использования пользовательской темы, которая «расширяет» тему по умолчанию.
::: tip СОВЕТ
Прежде чем приступить к работе, обязательно прочитайте главу [Пользовательская тема](./custom-theme), чтобы понять, как работают пользовательские темы.
@ -124,7 +124,7 @@ export default {
} satisfies Theme
```
Поскольку мы используем Vite, вы также можете использовать [глобальную функцию импорта](https://vitejs.dev/guide/features.html#glob-import) Vite для автоматической регистрации каталога компонентов.
Поскольку мы используем Vite, можно применять [глобальную функцию импорта](https://vitejs.dev/guide/features.html#glob-import) Vite для автоматической регистрации каталога компонентов.
## Слоты макета {#layout-slots}

@ -11,7 +11,7 @@ editLink: true
---
```
Многие параметры конфигурации сайта или темы по умолчанию имеют соответствующие опции в блоке метаданных. Вы можете использовать метаданные, чтобы переопределить определённое поведение только для текущей страницы. Подробности см. в [Справочнике по настройке метаданных](../reference/frontmatter-config).
Многие параметры конфигурации сайта или темы по умолчанию имеют соответствующие опции в блоке метаданных. Вы можете использовать метаданные, чтобы переопределить заданное поведение только для текущей страницы. Подробности см. в [Справочнике по настройке метаданных](../reference/frontmatter-config).
Вы также можете определить собственные метаданные, которые будут использоваться в динамических выражениях Vue на странице.

@ -63,7 +63,7 @@ VitePress — это пакет, предназначенный только д
### Мастер настройки {#setup-wizard}
VitePress поставляется с мастером настройки командной строки, который поможет вам создать базовый проект. После установки запустите мастер, запустив его:
VitePress поставляется с мастером настройки командной строки, который поможет вам создать базовый проект. После установки запустите мастер, выполнив команду:
::: code-group
@ -133,13 +133,13 @@ export default {
}
```
Вы также можете настроить поведение темы с помощью опции `themeConfig`. Загляните в главу [Настройка сайта](../reference/site-config) для получения подробной информации обо всех параметрах конфигурации.
Вы также можете настроить поведение темы с помощью опции `themeConfig`. Загляните в главу [Конфигурация сайта](../reference/site-config) для получения подробной информации обо всех настраиваемых параметрах.
### Исходные файлы {#source-files}
Файлы Markdown за пределами директории `.vitepress` считаются **исходными файлами**.
VitePress использует **маршрутизацию на основе файлов**: Каждый файл `.md` компилируется в соответствующий файл `.html` с тем же путем. Например, `index.md` будет скомпилирован в `index.html`, и его можно будет посетить по корневому пути `/` результирующего сайта VitePress.
VitePress использует **маршрутизацию на основе файлов**: Каждый файл `.md` компилируется в соответствующий файл `.html` с тем же путём. Например, `index.md` будет скомпилирован в `index.html`, и его можно будет посетить по корневому пути `/` результирующего сайта VitePress.
VitePress также предоставляет возможность генерировать чистые URL-адреса, переписывать пути и динамически генерировать страницы. Всё это будет рассмотрено в [Руководстве по маршрутизации](./routing).
@ -159,7 +159,7 @@ VitePress также предоставляет возможность гене
}
```
Скрипт `docs:dev` запустит локальный dev-сервер с мгновенными горячими обновлениями. Запустите его с помощью следующей команды:
Скрипт `docs:dev` запустит локальный dev-сервер с мгновенными горячими обновлениями. Выполните следующую команду:
::: code-group

@ -210,7 +210,7 @@ console.log('Привет, VitePress!')
:::
Кроме того, вы можете установить пользовательские заголовки глобально, добавив следующее содержимое в конфигурацию сайта, полезное, если вы пишете не на английском языке:
Кроме того, можно установить пользовательские заголовки глобально, добавив следующее содержимое в конфигурацию сайта, полезное, если вы пишете не на английском языке:
```ts
// config.ts
@ -269,7 +269,7 @@ export default defineConfig({
## Оповещения в стиле GitHub {#github-flavored-alerts}
VitePress также поддерживает [Оповещения в стиле GitHub](https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax#alerts) для отображения в виде призывов. Они будут отображаться так же, как и [пользовательские контейнеры](#custom-containers).
VitePress также поддерживает [Оповещения в стиле GitHub](https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax#alerts) для отображения в виде вставок. Они будут отображаться так же, как и [пользовательские контейнеры](#custom-containers).
```md
> [!NOTE]
@ -305,7 +305,7 @@ VitePress также поддерживает [Оповещения в стил
## Подсветка синтаксиса в блоках кода {#syntax-highlighting-in-code-blocks}
VitePress использует [Shiki](https://github.com/shikijs/shiki) для выделения синтаксиса языка в блоках кода Markdown с помощью цветного текста. Shiki поддерживает широкий спектр языков программирования. Всё, что вам нужно сделать, это добавить правильный псевдоним языка к начальным значкам блока кода:
VitePress использует [Shiki](https://github.com/shikijs/shiki) для выделения синтаксиса языка в блоках кода Markdown с помощью цветного текста. Shiki поддерживает широкий спектр языков программирования. Всё, что вам нужно сделать, это добавить правильный псевдоним языка к начальным обратным кавычкам блока кода:
**Разметка**
@ -375,7 +375,7 @@ export default {
}
```
Помимо одной строки, вы можете указать несколько отдельных строк, диапазонов или и то, и другое:
Помимо одной строки, можно указать несколько отдельных строк, диапазонов или и то, и другое:
- Диапазоны строк, например: `{5-8}`, `{3-10}`, `{10-17}`
- Несколько одиночных строк, например: `{4,7,9}`
@ -477,7 +477,7 @@ export default {
## Подсветка различий в блоках кода {#colored-diffs-in-code-blocks}
Добавление в строку комментариев `// [!code --]` или `// [!code ++]` создаст diff этой строки, сохраняя цвета блока кода.
Добавление в строку комментариев `// [!code --]` или `// [!code ++]` подсветит различие этой строки от другой, сохраняя цвета блока кода.
**Разметка**
@ -553,9 +553,9 @@ export default {
Более подробную информацию см. в секции [`markdown`](../reference/site-config#markdown).
Вы можете добавить метки `:line-numbers` / `:no-line-numbers` в ваши ограждённые блоки кода, чтобы переопределить значение, установленное в конфиге.
Вы можете добавить метки `:line-numbers` / `:no-line-numbers` в ваши изолированные блоки кода, чтобы переопределить значение, установленное в конфиге.
Вы также можете настроить номер начальной строки, добавив `=` после `:line-numbers`. Например, `:line-numbers=2` означает, что номера строк в блоках кода будут начинаться с `2`.
Вы также можете настроить номер начальной строки, добавив `=` после `:line-numbers`. Например, `:line-numbers=2` означает, что нумерация строк в блоках кода будет начинаться с `2`.
**Разметка**
@ -628,7 +628,7 @@ const line4 = 'Строка 4'
<<< @/snippets/snippet.js{2}
::: tip СОВЕТ
Значение `@` соответствует корню источника. По умолчанию это корень проекта VitePress, если не настроен `srcDir`. Альтернативно вы также можете импортировать из относительных путей:
Значение `@` соответствует корню источника. По умолчанию это корень проекта VitePress, если не настроен параметр `srcDir`. Альтернативно вы также можете импортировать из относительных путей:
```md
<<< ../snippets/snippet.js
@ -652,7 +652,7 @@ const line4 = 'Строка 4'
<<< @/snippets/snippet-with-region.js#snippet{1}
Вы также можете указать язык внутри фигурных скобок (`{}`) следующим образом:
Кроме того, можно указать язык внутри фигурных скобок (`{}`) следующим образом:
```md
<<< @/snippets/snippet.cs{c#}
@ -670,7 +670,7 @@ const line4 = 'Строка 4'
## Группы кодов {#code-groups}
Вы можете сгруппировать несколько блоков кода следующим образом:
Можно сгруппировать несколько блоков кода следующим образом:
**Разметка**

@ -6,7 +6,7 @@
Однако из-за отсутствия навигации SPA межстраничные ссылки будут приводить к полной перезагрузке страницы. После загрузки навигация в режиме MPA будет не такой мгновенной, как в режиме SPA.
Также обратите внимание, что «no-JS-by-default» («без JS по умолчанию») означает, что вы используете Vue исключительно как серверный язык шаблонов. Никаких обработчиков событий в браузере не будет, поэтому интерактивности не будет. Чтобы загрузить JavaScript со стороны клиента, вам нужно использовать специальный тег `<script client>`:
Также обратите внимание, что «no-JS-by-default» («без JS по умолчанию») означает, что вы используете Vue исключительно как серверный язык шаблонов. Никаких обработчиков событий в браузере не будет, как и интерактивности. Чтобы загрузить JavaScript со стороны клиента, вам нужно использовать специальный тег `<script client>`:
```html
<script client>

@ -188,7 +188,7 @@ export default {
}
```
Опция `rewrites` также поддерживает динамические параметры маршрута. В приведенном выше примере, если у вас много пакетов, перечислять все пути было бы скучно. Учитывая, что все они имеют одинаковую структуру файлов, вы можете упростить конфигурацию следующим образом:
Опция `rewrites` также поддерживает динамические параметры маршрута. В приведённом выше примере, если у вас много пакетов, перечислять все пути было бы скучно. Учитывая, что все они имеют одинаковую структуру файлов, можно упростить конфигурацию следующим образом:
```ts
export default {
@ -345,7 +345,7 @@ console.log(params.value)
### Рендеринг необработанного содержимого {#rendering-raw-content}
Параметры, передаваемые странице, будут сериализованы в полезной нагрузке клиентского JavaScript, поэтому вам следует избегать передачи в параметрах больших объемов данных, например, необработанного Markdown или HTML-контента, полученного из удаленной CMS.
Параметры, передаваемые странице, будут сериализованы в полезной нагрузке клиентского JavaScript, поэтому вам следует избегать передачи в параметрах больших объемов данных, например, необработанного Markdown или HTML-контента, полученного из удалённой CMS.
Вместо этого вы можете передавать такое содержимое на каждую страницу с помощью свойства `content` каждого объекта path:

@ -123,7 +123,7 @@ import CustomComponent from '../components/CustomComponent.vue'
Если компонент будет использоваться на большинстве страниц, его можно зарегистрировать глобально, настроив экземпляр приложения Vue. Пример смотрите в соответствующей главе [Расширение темы по умолчанию](./extending-default-theme#registering-global-components).
::: warning ВАЖНО
Убедитесь, что имя пользовательского компонента содержит дефис или написано в PascalCase. В противном случае он будет рассматриваться как встроенный элемент и заключен в тег `<p>`, что приведет к несоответствию гидратации, поскольку `<p>` не позволяет размещать внутри него блочные элементы.
Убедитесь, что имя пользовательского компонента содержит дефис или написано в PascalCase. В противном случае он будет рассматриваться как встроенный элемент и заключен в тег `<p>`, что приведёт к несоответствию гидратации, поскольку `<p>` не позволяет размещать внутри него блочные элементы.
:::
### Использование компонентов в заголовках <ComponentInHeader /> {#using-components-in-headers}
@ -177,7 +177,7 @@ HTML, обёрнутый `<code>`, будет отображаться как е
## Unescape в блоках кода {#unescape-in-code-blocks}
По умолчанию все изолированные блоки кода автоматически оборачиваются `v-pre`, поэтому внутри них не будет обрабатываться синтаксис Vue. Чтобы включить интерполяцию в стиле Vue внутри фигурных скобок, вы можете добавить к языку суффикс `-vue`, например `js-vue`:
По умолчанию все изолированные блоки кода автоматически оборачиваются `v-pre`, поэтому внутри них не будет обрабатываться синтаксис Vue. Чтобы включить интерполяцию в стиле Vue внутри фигурных скобок, можно добавить к языку суффикс `-vue`, например `js-vue`:
**Разметка**

@ -1,6 +1,6 @@
# Carbon Ads {#carbon-ads}
В VitePress встроена встроенная поддержка [Carbon Ads](https://www.carbonads.net/). Определив в конфиге учётные данные Carbon Ads, VitePress будет отображать рекламу на странице.
VitePress имеет встроенную поддержку [Carbon Ads](https://www.carbonads.net/). Определив в конфиге учётные данные Carbon Ads, VitePress будет отображать рекламу на странице.
```js
export default {
@ -13,10 +13,10 @@ export default {
}
```
Эти значения используются для вызова сценария carbon CDN, как показано ниже:
Эти значения используются для вызова сценария Carbon CDN, как показано ниже:
```js
;`//cdn.carbonads.com/carbon.js?serve=${code}&placement=${placement}`
```
Чтобы узнать больше о конфигурации Carbon Ads, посетите [веб-сайт Carbon Ads](https://www.carbonads.net/).
Чтобы узнать больше о настройке Carbon Ads, посетите [веб-сайт Carbon Ads](https://www.carbonads.net/).

@ -299,7 +299,7 @@ new Crawler({
lvl1: '.content h1',
content: '.content p, .content li',
lvl0: {
selectors: '',
selectors: 'section.has-active div h2',
defaultValue: 'Documentation'
},
lvl2: '.content h2',

@ -161,6 +161,12 @@ aside: false
Уровни заголовков в оглавлении для отображения на странице. Это то же самое, что и [config.themeConfig.outline.level](./default-theme-config#outline), и оно переопределяет значение, установленное в конфигурации сайта.
```yaml
---
outline: [2, 4]
---
```
### lastUpdated {#lastupdated}
- Тип: `boolean | Date`

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

@ -289,7 +289,7 @@ new Crawler({
lvl1: '.content h1',
content: '.content p, .content li',
lvl0: {
selectors: '',
selectors: 'section.has-active div h2',
defaultValue: 'Documentation'
},
lvl2: '.content h2',

@ -1,6 +1,6 @@
{
"name": "vitepress",
"version": "1.3.4",
"version": "1.4.0",
"description": "Vite & Vue powered static site generator",
"keywords": [
"vite",
@ -98,22 +98,23 @@
"*": "prettier --write --ignore-unknown"
},
"dependencies": {
"@docsearch/css": "^3.6.1",
"@docsearch/js": "^3.6.1",
"@shikijs/core": "^1.15.2",
"@shikijs/transformers": "^1.15.2",
"@docsearch/css": "^3.6.2",
"@docsearch/js": "^3.6.2",
"@shikijs/core": "^1.22.0",
"@shikijs/transformers": "^1.22.0",
"@shikijs/types": "^1.22.0",
"@types/markdown-it": "^14.1.2",
"@vitejs/plugin-vue": "^5.1.3",
"@vue/devtools-api": "^7.3.9",
"@vue/shared": "^3.4.38",
"@vueuse/core": "^11.0.3",
"@vueuse/integrations": "^11.0.3",
"focus-trap": "^7.5.4",
"@vitejs/plugin-vue": "^5.1.4",
"@vue/devtools-api": "^7.4.6",
"@vue/shared": "^3.5.11",
"@vueuse/core": "^11.1.0",
"@vueuse/integrations": "^11.1.0",
"focus-trap": "^7.6.0",
"mark.js": "8.11.1",
"minisearch": "^7.1.0",
"shiki": "^1.15.2",
"vite": "^5.4.2",
"vue": "^3.4.38"
"shiki": "^1.22.0",
"vite": "^5.4.8",
"vue": "^3.5.11"
},
"devDependencies": {
"@clack/prompts": "^0.7.0",
@ -124,12 +125,12 @@
"@mdit-vue/plugin-title": "^2.1.3",
"@mdit-vue/plugin-toc": "^2.1.3",
"@mdit-vue/shared": "^2.1.3",
"@polka/compression": "^1.0.0-next.26",
"@rollup/plugin-alias": "^5.1.0",
"@rollup/plugin-commonjs": "^26.0.1",
"@polka/compression": "^1.0.0-next.28",
"@rollup/plugin-alias": "^5.1.1",
"@rollup/plugin-commonjs": "^28.0.0",
"@rollup/plugin-json": "^6.1.0",
"@rollup/plugin-node-resolve": "^15.2.3",
"@rollup/plugin-replace": "^5.0.7",
"@rollup/plugin-node-resolve": "^15.3.0",
"@rollup/plugin-replace": "^6.0.1",
"@types/cross-spawn": "^6.0.6",
"@types/debug": "^4.1.12",
"@types/fs-extra": "^11.0.4",
@ -140,23 +141,23 @@
"@types/markdown-it-emoji": "^3.0.1",
"@types/micromatch": "^4.0.9",
"@types/minimist": "^1.2.5",
"@types/node": "^22.5.1",
"@types/node": "^22.7.4",
"@types/postcss-prefix-selector": "^1.16.3",
"@types/prompts": "^2.4.9",
"chokidar": "^3.6.0",
"conventional-changelog-cli": "^5.0.0",
"cross-spawn": "^7.0.3",
"debug": "^4.3.6",
"esbuild": "^0.23.1",
"execa": "^9.3.1",
"debug": "^4.3.7",
"esbuild": "^0.24.0",
"execa": "^9.4.0",
"fs-extra": "^11.2.0",
"get-port": "^7.1.0",
"gray-matter": "^4.0.3",
"lint-staged": "^15.2.9",
"lint-staged": "^15.2.10",
"lodash.template": "^4.5.0",
"lru-cache": "^11.0.0",
"lru-cache": "^11.0.1",
"markdown-it": "^14.1.0",
"markdown-it-anchor": "^9.1.0",
"markdown-it-anchor": "^9.2.0",
"markdown-it-attrs": "^4.2.0",
"markdown-it-container": "^4.0.0",
"markdown-it-emoji": "^3.0.0",
@ -166,17 +167,17 @@
"nanoid": "^5.0.7",
"ora": "^8.1.0",
"p-map": "^7.0.2",
"path-to-regexp": "^6.2.2",
"picocolors": "^1.0.1",
"path-to-regexp": "^6.3.0",
"picocolors": "^1.1.0",
"pkg-dir": "^8.0.0",
"playwright-chromium": "^1.46.1",
"polka": "^1.0.0-next.25",
"postcss-prefix-selector": "^1.16.1",
"playwright-chromium": "^1.47.2",
"polka": "^1.0.0-next.28",
"postcss-prefix-selector": "^2.0.0",
"prettier": "^3.3.3",
"prompts": "^2.4.2",
"punycode": "^2.3.1",
"rimraf": "^6.0.1",
"rollup": "^4.21.2",
"rollup": "^4.24.0",
"rollup-plugin-dts": "^6.1.1",
"rollup-plugin-esbuild": "^6.1.1",
"semver": "^7.6.3",
@ -184,11 +185,11 @@
"sirv": "^2.0.4",
"sitemap": "^8.0.0",
"supports-color": "^9.4.0",
"tinyglobby": "^0.2.5",
"typescript": "^5.5.4",
"vitest": "^2.0.5",
"vue-tsc": "^2.1.4",
"wait-on": "^8.0.0"
"tinyglobby": "^0.2.9",
"typescript": "^5.6.2",
"vitest": "^2.1.2",
"vue-tsc": "^2.1.6",
"wait-on": "^8.0.1"
},
"peerDependencies": {
"markdown-it-mathjax3": "^4",
@ -202,7 +203,7 @@
"optional": true
}
},
"packageManager": "pnpm@9.9.0",
"packageManager": "pnpm@9.12.0",
"pnpm": {
"peerDependencyRules": {
"ignoreMissing": [

File diff suppressed because it is too large Load Diff

@ -87,7 +87,7 @@ function createHeadElement([tag, attrs, innerHTML]: HeadConfig) {
if (innerHTML) {
el.innerHTML = innerHTML
}
if (tag === 'script' && !attrs.async) {
if (tag === 'script' && attrs.async == null) {
// async is true by default for dynamically created scripts
;(el as HTMLScriptElement).async = false
}

@ -1,5 +1,5 @@
import siteData from '@siteData'
import { useDark } from '@vueuse/core'
import { useDark, usePreferredDark } from '@vueuse/core'
import {
computed,
inject,
@ -79,13 +79,15 @@ export function initData(route: Route): VitePressData {
const isDark =
appearance === 'force-dark'
? ref(true)
: appearance
? useDark({
storageKey: APPEARANCE_KEY,
initialValue: () => (appearance === 'dark' ? 'dark' : 'auto'),
...(typeof appearance === 'object' ? appearance : {})
})
: ref(false)
: appearance === 'force-auto'
? usePreferredDark()
: appearance
? useDark({
storageKey: APPEARANCE_KEY,
initialValue: () => (appearance === 'dark' ? 'dark' : 'auto'),
...(typeof appearance === 'object' ? appearance : {})
})
: ref(false)
const hashRef = ref(inBrowser ? location.hash : '')

@ -78,6 +78,12 @@ function onBlur() {
color: var(--vp-c-brand-2);
}
.button[aria-expanded="false"] + .menu {
opacity: 0;
visibility: hidden;
transform: translateY(0);
}
.VPFlyout:hover .menu,
.button[aria-expanded="true"] + .menu {
opacity: 1;
@ -85,12 +91,6 @@ function onBlur() {
transform: translateY(0);
}
.button[aria-expanded="false"] + .menu {
opacity: 0;
visibility: hidden;
transform: translateY(0);
}
.button {
display: flex;
align-items: center;

@ -440,10 +440,20 @@ function formMarkRegex(terms: Set<string>) {
<input
ref="searchInput"
v-model="filterText"
:placeholder="buttonText"
id="localsearch-input"
:aria-activedescendant="selectedIndex > -1 ? ('localsearch-item-' + selectedIndex) : undefined"
aria-autocomplete="both"
:aria-controls="results?.length ? 'localsearch-list' : undefined"
aria-labelledby="localsearch-label"
autocapitalize="off"
autocomplete="off"
autocorrect="off"
class="search-input"
id="localsearch-input"
enterkeyhint="go"
maxlength="64"
:placeholder="buttonText"
spellcheck="false"
type="search"
/>
<div class="search-actions">
<button
@ -482,8 +492,9 @@ function formMarkRegex(terms: Set<string>) {
<li
v-for="(p, index) in results"
:key="p.id"
role="option"
:id="'localsearch-item-' + index"
:aria-selected="selectedIndex === index ? 'true' : 'false'"
role="option"
>
<a
:href="p.id"

@ -1,9 +1,5 @@
/* webfont-marker-begin */
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap');
html body {
font-synthesis: style;
}
@import url('https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap');
/* webfont-marker-end */
@font-face {

@ -19,13 +19,12 @@ import MarkdownIt from 'markdown-it'
import anchorPlugin from 'markdown-it-anchor'
import attrsPlugin from 'markdown-it-attrs'
import { full as emojiPlugin } from 'markdown-it-emoji'
import type { BuiltinTheme, Highlighter } from 'shiki'
import type {
BuiltinTheme,
Highlighter,
LanguageInput,
ShikiTransformer,
ThemeRegistrationAny
} from 'shiki'
} from '@shikijs/types'
import type { Logger } from 'vite'
import { containerPlugin, type ContainerOptions } from './plugins/containers'
import { gitHubAlertsPlugin } from './plugins/githubAlerts'

@ -90,7 +90,7 @@ export async function highlight(
}
]
const vueRE = /-vue$/
const vueRE = /-vue(?=:|$)/
const lineNoStartRE = /=(\d*)/
const lineNoRE = /:(no-)?line-numbers(=\d*)?$/
const mustacheRE = /\{\{.*?\}\}/g

@ -63,14 +63,14 @@ export async function createMarkdownToVueRenderFn(
const dynamicRoutes = new Map(
siteConfig?.dynamicRoutes?.routes.map((r) => [
r.fullPath,
path.join(srcDir, r.route)
slash(path.join(srcDir, r.route))
]) || []
)
const rewrites = new Map(
Object.entries(siteConfig?.rewrites.map || {}).map(([key, value]) => [
path.join(srcDir, key),
path.join(srcDir, value!)
slash(path.join(srcDir, key)),
slash(path.join(srcDir, value!))
]) || []
)

@ -6,22 +6,35 @@ export function resolveRewrites(
pages: string[],
userRewrites: UserConfig['rewrites']
) {
const rewriteRules = Object.entries(userRewrites || {}).map(([from, to]) => ({
toPath: compile(`/${to}`, { validate: false }),
matchUrl: match(from.startsWith('^') ? new RegExp(from) : from)
}))
const pageToRewrite: Record<string, string> = {}
const rewriteToPage: Record<string, string> = {}
if (rewriteRules.length) {
if (typeof userRewrites === 'function') {
for (const page of pages) {
for (const { matchUrl, toPath } of rewriteRules) {
const res = matchUrl(page)
if (res) {
const dest = toPath(res.params).slice(1)
pageToRewrite[page] = dest
rewriteToPage[dest] = page
break
const dest = userRewrites(page)
if (dest && dest !== page) {
pageToRewrite[page] = dest
rewriteToPage[dest] = page
}
}
} else if (typeof userRewrites === 'object') {
const rewriteRules = Object.entries(userRewrites || {}).map(
([from, to]) => ({
toPath: compile(`/${to}`, { validate: false }),
matchUrl: match(from.startsWith('^') ? new RegExp(from) : from)
})
)
if (rewriteRules.length) {
for (const page of pages) {
for (const { matchUrl, toPath } of rewriteRules) {
const res = matchUrl(page)
if (res) {
const dest = toPath(res.params).slice(1)
pageToRewrite[page] = dest
rewriteToPage[dest] = page
break
}
}
}
}

@ -162,7 +162,7 @@ export interface UserConfig<ThemeConfig = any>
*
* source -> destination
*/
rewrites?: Record<string, string>
rewrites?: Record<string, string> | ((id: string) => string)
/**
* @experimental

Loading…
Cancel
Save