|
|
---
|
|
|
outline: deep
|
|
|
---
|
|
|
|
|
|
# Маршрутизация {#routing}
|
|
|
|
|
|
## Маршрутизация на основе файлов {#file-based-routing}
|
|
|
|
|
|
VitePress использует маршрутизацию на основе файлов, что означает, что сгенерированные HTML-страницы отображаются на основе структуры папок исходных файлов Markdown. Например, при следующей структуре папок:
|
|
|
|
|
|
```
|
|
|
.
|
|
|
├─ guide
|
|
|
│ ├─ getting-started.md
|
|
|
│ └─ index.md
|
|
|
├─ index.md
|
|
|
└─ prologue.md
|
|
|
```
|
|
|
|
|
|
Сгенерированные HTML-страницы будут выглядеть так:
|
|
|
|
|
|
```
|
|
|
index.md --> /index.html (доступна по адресу /)
|
|
|
prologue.md --> /prologue.html
|
|
|
guide/index.md --> /guide/index.html (доступна по адресу /guide/)
|
|
|
guide/getting-started.md --> /guide/getting-started.html
|
|
|
```
|
|
|
|
|
|
Полученный HTML можно разместить на любом веб-сервере, который может обслуживать статические файлы.
|
|
|
|
|
|
## Корневая директория и директория с исходными файлами {#root-and-source-directory}
|
|
|
|
|
|
В файловой структуре проекта VitePress есть два важных понятия: **корень проекта** и **директория с исходными файлами**.
|
|
|
|
|
|
### Корень проекта {#project-root}
|
|
|
|
|
|
Корень проекта — это место, где VitePress будет пытаться искать специальный каталог `.vitepress`. Директория `.vitepress` — это зарезервированное место для конфигурационного файла VitePress, кэша dev-сервера, результатов сборки и дополнительного кода настройки темы.
|
|
|
|
|
|
Когда вы запускаете `vitepress dev` или `vitepress build` из командной строки, VitePress будет использовать текущий рабочий каталог в качестве корня проекта. Чтобы указать подкаталог в качестве корневого, нужно передать команде относительный путь. Например, если ваш проект VitePress находится в папке `./docs`, вам следует выполнить команду `vitepress dev docs`:
|
|
|
|
|
|
```
|
|
|
.
|
|
|
├─ docs # корень проекта
|
|
|
│ ├─ .vitepress # директория с настройками
|
|
|
│ ├─ getting-started.md
|
|
|
│ └─ index.md
|
|
|
└─ ...
|
|
|
```
|
|
|
|
|
|
```sh
|
|
|
vitepress dev docs
|
|
|
```
|
|
|
|
|
|
В результате получится следующее сопоставление источника с HTML:
|
|
|
|
|
|
```
|
|
|
docs/index.md --> /index.html (доступна по адресу /)
|
|
|
docs/getting-started.md --> /getting-started.html
|
|
|
```
|
|
|
|
|
|
### Директория с исходными файлами {#source-directory}
|
|
|
|
|
|
Директория с исходными файлами — это место, где хранятся ваши исходные файлы Markdown. По умолчанию она совпадает с корнем проекта. Однако вы можете настроить её с помощью параметра [`srcDir`](../reference/site-config#srcdir).
|
|
|
|
|
|
Опция `srcDir` разрешается относительно корня проекта. Например, с помощью `srcDir: 'src'`, ваша файловая структура будет выглядеть следующим образом:
|
|
|
|
|
|
```
|
|
|
. # корень проекта
|
|
|
├─ .vitepress # директория с настройками
|
|
|
└─ src # директория с исходными файлами
|
|
|
├─ getting-started.md
|
|
|
└─ index.md
|
|
|
```
|
|
|
|
|
|
Итоговое сопоставление исходного кода с HTML:
|
|
|
|
|
|
```
|
|
|
src/index.md --> /index.html (доступна по адресу /)
|
|
|
src/getting-started.md --> /getting-started.html
|
|
|
```
|
|
|
|
|
|
## Связи между страницами {#linking-between-pages}
|
|
|
|
|
|
При создании ссылок между страницами можно использовать как абсолютные, так и относительные пути. Обратите внимание, что хотя расширения `.md` и `.html` будут работать, лучше всего опускать расширения файлов, чтобы VitePress мог генерировать конечные URL на основе вашего конфига.
|
|
|
|
|
|
```md
|
|
|
<!-- Будут работать -->
|
|
|
|
|
|
[Первые шаги](./getting-started)
|
|
|
[Первые шаги](../guide/getting-started)
|
|
|
|
|
|
<!-- Не будут работать -->
|
|
|
|
|
|
[Первые шаги](./getting-started.md)
|
|
|
[Первые шаги](./getting-started.html)
|
|
|
```
|
|
|
|
|
|
Узнайте больше о ссылках на такие ресурсы, как изображения, в главе [Обработка ресурсов](./asset-handling).
|
|
|
|
|
|
### Ссылки на страницы, не принадлежащие VitePress {#linking-to-non-vitepress-pages}
|
|
|
|
|
|
Если вы хотите создать ссылку на страницу вашего сайта, которая не создана VitePress, вам нужно будет либо использовать полный URL-адрес (откроется в новой вкладке), либо явно указать цель:
|
|
|
|
|
|
**Разметка**
|
|
|
|
|
|
```md
|
|
|
[Ссылка на pure.html](/pure.html){target="_self"}
|
|
|
```
|
|
|
|
|
|
**Результат**
|
|
|
|
|
|
[Ссылка на pure.html](/pure.html){target="_self"}
|
|
|
|
|
|
::: tip Примечание
|
|
|
|
|
|
В ссылках Markdown к URL-адресу автоматически добавляется значение параметра `base`. Это означает, что если вы хотите создать ссылку на страницу за пределами `base`, вам понадобится что-то вроде `../../pure.html` в ссылке (разрешаемой браузером относительно текущей страницы).
|
|
|
|
|
|
Альтернативно можно напрямую использовать синтаксис тега ссылки:
|
|
|
|
|
|
```md
|
|
|
<a href="/pure.html" target="_self">Ссылка на pure.html</a>
|
|
|
```
|
|
|
|
|
|
:::
|
|
|
|
|
|
## Создание чистого URL-адреса {#generating-clean-url}
|
|
|
|
|
|
::: warning Требуется поддержка сервера
|
|
|
Для обслуживания чистых URL-адресов с помощью VitePress требуется поддержка на стороне сервера.
|
|
|
:::
|
|
|
|
|
|
По умолчанию VitePress разрешает входящие ссылки на URL-адреса, заканчивающиеся на `.html`. Однако некоторые пользователи могут предпочесть «Чистые URL-адреса» без расширения `.html` — например, `example.com/path` вместо `example.com/path.html`.
|
|
|
|
|
|
Некоторые серверы или хостинговые платформы (например, Netlify, Vercel, GitHub Pages) предоставляют возможность сопоставлять URL-адрес типа `/foo` с `/foo.html`, если он существует, без перенаправления:
|
|
|
|
|
|
- Страницы Netlify и GitHub поддерживают это по умолчанию.
|
|
|
- Vercel требует включить [опцию `cleanUrls` в `vercel.json`](https://vercel.com/docs/concepts/projects/project-configuration#cleanurls).
|
|
|
|
|
|
Если эта функция вам доступна, вы также можете включить собственную опцию конфигурации VitePress [`cleanUrls`](../reference/site-config#cleanurls), чтобы обеспечить следующее поведение:
|
|
|
|
|
|
- Входящие ссылки между страницами генерируются без расширения `.html`.
|
|
|
- Если текущий путь заканчивается на `.html`, маршрутизатор выполнит перенаправление на стороне клиента на путь без расширений.
|
|
|
|
|
|
Однако если вы не можете настроить свой сервер с такой поддержкой, вам придётся вручную прибегнуть к следующей структуре каталогов:
|
|
|
|
|
|
```
|
|
|
.
|
|
|
├─ getting-started
|
|
|
│ └─ index.md
|
|
|
├─ installation
|
|
|
│ └─ index.md
|
|
|
└─ index.md
|
|
|
```
|
|
|
|
|
|
## Перезапись маршрутов {#route-rewrites}
|
|
|
|
|
|
Вы можете настроить сопоставление между структурой исходного каталога и создаваемыми страницами. Это полезно, когда у вас сложная структура проекта. Допустим, у вас есть монорепо с несколькими пакетами, и вы хотите поместить документацию вместе с исходными файлами, как это сделано здесь:
|
|
|
|
|
|
```
|
|
|
.
|
|
|
├─ packages
|
|
|
│ ├─ pkg-a
|
|
|
│ │ └─ src
|
|
|
│ │ ├─ pkg-a-code.ts
|
|
|
│ │ └─ pkg-a-docs.md
|
|
|
│ └─ pkg-b
|
|
|
│ └─ src
|
|
|
│ ├─ pkg-b-code.ts
|
|
|
│ └─ pkg-b-docs.md
|
|
|
```
|
|
|
|
|
|
И вы хотите, чтобы страницы VitePress генерировались следующим образом:
|
|
|
|
|
|
```
|
|
|
packages/pkg-a/src/pkg-a-docs.md --> /pkg-a/index.html
|
|
|
packages/pkg-b/src/pkg-b-docs.md --> /pkg-b/index.html
|
|
|
```
|
|
|
|
|
|
Этого можно добиться, настроив опцию [`rewrites`](../reference/site-config#rewrites) следующим образом:
|
|
|
|
|
|
```ts
|
|
|
// .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'
|
|
|
}
|
|
|
}
|
|
|
```
|
|
|
|
|
|
Опция `rewrites` также поддерживает динамические параметры маршрута. В приведенном выше примере, если у вас много пакетов, перечислять все пути было бы скучно. Учитывая, что все они имеют одинаковую структуру файлов, вы можете упростить конфигурацию следующим образом:
|
|
|
|
|
|
```ts
|
|
|
export default {
|
|
|
rewrites: {
|
|
|
'packages/:pkg/src/(.*)': ':pkg/index.md'
|
|
|
}
|
|
|
}
|
|
|
```
|
|
|
|
|
|
Пути перезаписи компилируются с помощью пакета `path-to-regexp` — обратитесь к [его документации](https://github.com/pillarjs/path-to-regexp#parameters) за более сложным синтаксисом.
|
|
|
|
|
|
::: warning Относительные ссылки с переписыванием
|
|
|
|
|
|
Когда переписывание включено, **относительные ссылки должны быть основаны на переписанных путях**. Например, чтобы создать относительную ссылку с `packages/pkg-a/src/pkg-a-code.md` на `packages/pkg-b/src/pkg-b-code.md`, нужно использовать:
|
|
|
|
|
|
```md
|
|
|
[Ссылка на PKG B](../pkg-b/pkg-b-code)
|
|
|
```
|
|
|
|
|
|
:::
|
|
|
|
|
|
## Динамические маршруты {#dynamic-routes}
|
|
|
|
|
|
Вы можете создать множество страниц, используя один файл Markdown и динамические данные. Например, вы можете создать файл `packages/[pkg].md`, который будет генерировать соответствующую страницу для каждого пакета в проекте. Здесь сегмент `[pkg]` является **параметром** маршрута, который отличает каждую страницу от других.
|
|
|
|
|
|
### Файл загрузчика путей {#paths-loader-file}
|
|
|
|
|
|
Поскольку VitePress — это генератор статических сайтов, возможные пути страниц должны быть определены во время сборки. Поэтому динамическая маршрутная страница **должна** сопровождаться **файлом загрузчика путей**. Для `packages/[pkg].md` нам понадобится `packages/[pkg].paths.js` (`.ts` также поддерживается):
|
|
|
|
|
|
```
|
|
|
.
|
|
|
└─ packages
|
|
|
├─ [pkg].md # шаблон маршрута
|
|
|
└─ [pkg].paths.js # загрузчик путей маршрута
|
|
|
```
|
|
|
|
|
|
Загрузчик путей должен предоставлять объект с методом `paths` в качестве экспорта по умолчанию. Метод `paths` должен возвращать массив объектов со свойством `params`. Для каждого из этих объектов будет создана соответствующая страница.
|
|
|
|
|
|
Дан следующий массив `paths`:
|
|
|
|
|
|
```js
|
|
|
// packages/[pkg].paths.js
|
|
|
export default {
|
|
|
paths() {
|
|
|
return [{ params: { pkg: 'foo' } }, { params: { pkg: 'bar' } }]
|
|
|
}
|
|
|
}
|
|
|
```
|
|
|
|
|
|
Сгенерированные HTML-страницы будут выглядеть так:
|
|
|
|
|
|
```
|
|
|
.
|
|
|
└─ packages
|
|
|
├─ foo.html
|
|
|
└─ bar.html
|
|
|
```
|
|
|
|
|
|
### Несколько параметров {#multiple-params}
|
|
|
|
|
|
Динамический маршрут может содержать несколько параметров:
|
|
|
|
|
|
**Структура файлов**
|
|
|
|
|
|
```
|
|
|
.
|
|
|
└─ packages
|
|
|
├─ [pkg]-[version].md
|
|
|
└─ [pkg]-[version].paths.js
|
|
|
```
|
|
|
|
|
|
**Загрузчик путей**
|
|
|
|
|
|
```js
|
|
|
export default {
|
|
|
paths: () => [
|
|
|
{ params: { pkg: 'foo', version: '1.0.0' } },
|
|
|
{ params: { pkg: 'foo', version: '2.0.0' } },
|
|
|
{ params: { pkg: 'bar', version: '1.0.0' } },
|
|
|
{ params: { pkg: 'bar', version: '2.0.0' } }
|
|
|
]
|
|
|
}
|
|
|
```
|
|
|
|
|
|
**Результат**
|
|
|
|
|
|
```
|
|
|
.
|
|
|
└─ packages
|
|
|
├─ foo-1.0.0.html
|
|
|
├─ foo-2.0.0.html
|
|
|
├─ bar-1.0.0.html
|
|
|
└─ bar-2.0.0.html
|
|
|
```
|
|
|
|
|
|
### Динамически генерируемые пути {#dynamically-generating-paths}
|
|
|
|
|
|
Модуль загрузчика путей запускается в Node.js и выполняется только во время сборки. Вы можете динамически генерировать массив путей, используя любые данные, как локальные, так и удалённые.
|
|
|
|
|
|
Генерация путей из локальных файлов:
|
|
|
|
|
|
```js
|
|
|
import fs from 'fs'
|
|
|
|
|
|
export default {
|
|
|
paths() {
|
|
|
return fs.readdirSync('packages').map((pkg) => {
|
|
|
return { params: { pkg } }
|
|
|
})
|
|
|
}
|
|
|
}
|
|
|
```
|
|
|
|
|
|
Генерация путей из удалённых данных:
|
|
|
|
|
|
```js
|
|
|
export default {
|
|
|
async paths() {
|
|
|
const pkgs = await (await fetch('https://my-api.com/packages')).json()
|
|
|
|
|
|
return pkgs.map((pkg) => {
|
|
|
return {
|
|
|
params: {
|
|
|
pkg: pkg.name,
|
|
|
version: pkg.version
|
|
|
}
|
|
|
}
|
|
|
})
|
|
|
}
|
|
|
}
|
|
|
```
|
|
|
|
|
|
### Доступ к параметрам на странице {#accessing-params-in-page}
|
|
|
|
|
|
Вы можете использовать параметры для передачи дополнительных данных на каждую страницу. Файл маршрута Markdown может получить доступ к параметрам текущей страницы в выражениях Vue через глобальное свойство `$params`:
|
|
|
|
|
|
```md
|
|
|
- package name: {{ $params.pkg }}
|
|
|
- version: {{ $params.version }}
|
|
|
```
|
|
|
|
|
|
Вы также можете получить доступ к параметрам текущей страницы через Runtime API [`useData`](../reference/runtime-api#usedata). Это доступно как в файлах Markdown, так и в компонентах Vue:
|
|
|
|
|
|
```vue
|
|
|
<script setup>
|
|
|
import { useData } from 'vitepress'
|
|
|
|
|
|
// params — это ref-ссылка Vue
|
|
|
const { params } = useData()
|
|
|
|
|
|
console.log(params.value)
|
|
|
</script>
|
|
|
```
|
|
|
|
|
|
### Рендеринг необработанного содержимого {#rendering-raw-content}
|
|
|
|
|
|
Параметры, передаваемые странице, будут сериализованы в полезной нагрузке клиентского JavaScript, поэтому вам следует избегать передачи в параметрах больших объемов данных, например, необработанного Markdown или HTML-контента, полученного из удаленной CMS.
|
|
|
|
|
|
Вместо этого вы можете передавать такое содержимое на каждую страницу с помощью свойства `content` каждого объекта path:
|
|
|
|
|
|
```js
|
|
|
export default {
|
|
|
async paths() {
|
|
|
const posts = await (await fetch('https://my-cms.com/blog-posts')).json()
|
|
|
|
|
|
return posts.map((post) => {
|
|
|
return {
|
|
|
params: { id: post.id },
|
|
|
content: post.content // необработанный Markdown или HTML
|
|
|
}
|
|
|
})
|
|
|
}
|
|
|
}
|
|
|
```
|
|
|
|
|
|
Затем используйте следующий специальный синтаксис, чтобы отобразить содержимое как часть самого файла Markdown:
|
|
|
|
|
|
```md
|
|
|
<!-- @content -->
|
|
|
```
|