pull/1593/head
Xavi Lee 3 years ago
parent 7d102761cf
commit 8a2ac4a1b0

@ -1,5 +1,7 @@
# Asset Handling
## Referencing Static Assets
All Markdown files are compiled into Vue components and processed by [Vite](https://vitejs.dev/guide/assets.html). You can, **and should**, reference any assets using relative URLs:
```md
@ -10,19 +12,21 @@ You can reference static assets in your markdown files, your `*.vue` components
Common image, media, and font filetypes are detected and included as assets automatically.
All referenced assets, including those using absolute paths, will be copied to the dist folder with a hashed file name in the production build. Never-referenced assets will not be copied. Image assets smaller than 4kb will be base64 inlined - this can be configured via the [`vite`](/reference/site-config#vite) config option.
All referenced assets, including those using absolute paths, will be copied to the output directory with a hashed file name in the production build. Never-referenced assets will not be copied. Image assets smaller than 4kb will be base64 inlined - this can be configured via the [`vite`](../reference/site-config#vite) config option.
All **static** path references, including absolute paths, should be based on your working directory structure.
## Public Files
## The Public Directory
Sometimes you may need to provide static assets that are not directly referenced in any of your Markdown or theme components, or you may want to serve certain files with the original filename. Examples of such files include `robot.txt`, favicons, and PWA icons.
Sometimes you may need to provide static assets that are not directly referenced in any of your Markdown or theme components (for example, favicons and PWA icons). The `public` directory under project root (`docs` folder if you're running `vitepress build docs`) can be used as an escape hatch to provide static assets that either are never referenced in source code (e.g. `robots.txt`), or must retain the exact same file name (without hashing).
You can place these files in the `public` directory under the [source directory](./routing#source-directory). For example, if your project root is `./docs` and using default source directory location, then your public directory will be `./docs/public`.
Assets placed in `public` will be copied to the root of the dist directory as-is.
Assets placed in `public` will be copied to the root of the output directory as-is.
Note that you should reference files placed in `public` using root absolute path - for example, `public/icon.png` should always be referenced in source code as `/icon.png`.
There is one exception to this: if you have an HTML page in `public` and link to it from the main site, the router will yield a 404 by default. To get around this, VitePress provides a `pathname://` protocol which allows you to link to another page in the same domain as if the link is external. Contrast these two links:
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>
@ -45,7 +49,7 @@ However, if you are authoring a theme component that links to assets dynamically
<img :src="theme.logoPath" />
```
In this case it is recommended to wrap the path with the [`withBase` helper](/reference/runtime-api#withbase) provided by VitePress:
In this case it is recommended to wrap the path with the [`withBase` helper](../reference/runtime-api#withbase) provided by VitePress:
```vue
<script setup>

@ -6,7 +6,7 @@ outline: deep
## General Workflow
Connecting VitePress to a CMS will largely revolve around [Dynamic Routes](/guide/routing#dynamic-routes). Make sure to understand how it works before proceeding.
Connecting VitePress to a CMS will largely revolve around [Dynamic Routes](./routing#dynamic-routes). Make sure to understand how it works before proceeding.
Since each CMS will work differently, here we can only provide a generic workflow that you will need to adapt to your specific scenario.

@ -66,11 +66,11 @@ export default {
The default export is the only contract for a custom theme, and only the `Layout` property is required. So technically, a VitePress theme can be as simple as a single Vue component.
Inside your layout component, it works just like a normal Vite + Vue 3 application. Do note the theme also needs to be [SSR-compatible](./using-vue#browser-api-access-restrictions).
Inside your layout component, it works just like a normal Vite + Vue 3 application. Do note the theme also needs to be [SSR-compatible](./ssr-compat).
## Building a Layout
The most basic layout component needs to contain a [`<Content />`](/reference/runtime-api#content) component:
The most basic layout component needs to contain a [`<Content />`](../reference/runtime-api#content) component:
```vue
<!-- .vitepress/theme/Layout.vue -->
@ -100,7 +100,7 @@ const { page } = useData()
</template>
```
The [`useData()`](/reference/runtime-api#usedata) helper provides us with all the runtime data we need to conditionally render different layouts. One of the other data we can access is the current page's frontmatter. We can leverage this to allow the end user to control the layout in each page. For example, the user can indicate the page should use a special home page layout with:
The [`useData()`](../reference/runtime-api#usedata) helper provides us with all the runtime data we need to conditionally render different layouts. One of the other data we can access is the current page's frontmatter. We can leverage this to allow the end user to control the layout in each page. For example, the user can indicate the page should use a special home page layout with:
```md
---
@ -150,7 +150,7 @@ const { page, frontmatter } = useData()
</template>
```
Consult the [Runtime API Reference](/reference/runtime-api) for everything available in theme components. In addition, you can leverage [Build-Time Data Loading](./data-loading) to generate data-driven layout - for example, a page that lists all blog posts in the current project.
Consult the [Runtime API Reference](../reference/runtime-api) for everything available in theme components. In addition, you can leverage [Build-Time Data Loading](./data-loading) to generate data-driven layout - for example, a page that lists all blog posts in the current project.
## Distributing a Custom Theme

@ -56,29 +56,118 @@ export default {
When you need to generate data based on local files, you should use the `watch` option in the data loader so that changes made to these files can trigger hot updates.
The `watch` option is also convenient in that you can use [glob patterns](https://github.com/mrmlnc/fast-glob#pattern-syntax) to match multiple files. The patterns can be relative to the loader file itself, and the `load()` function will receive the matched files as absolute paths:
The `watch` option is also convenient in that you can use [glob patterns](https://github.com/mrmlnc/fast-glob#pattern-syntax) to match multiple files. The patterns can be relative to the loader file itself, and the `load()` function will receive the matched files as absolute paths.
The following example shows loading CSV files and transforming them into JSON using [csv-parse](https://github.com/adaltas/node-csv/tree/master/packages/csv-parse/). Because this file only executes at build time, you will not be shipping the CSV parser to the client!
```js
import fs from 'node:fs'
import parseFrontmatter from 'gray-matter'
import { parse } from 'csv-parse/sync'
export default {
// watch all blog posts
watch: ['./posts/*.md'],
watch: ['./data/*.csv'],
load(watchedFiles) {
// watchedFiles will be an array of absolute paths of the matched files.
// generate an array of blog post metadata that can be used to render
// a list in the theme layout
return watchedFiles.map(file => {
const content = fs.readFileSync(file, 'utf-8')
const { data, excerpt } = parseFrontmatter(content)
return {
file,
data,
excerpt
return parse(fs.readFileSync(file, 'utf-8'), {
columns: true,
skip_empty_lines: true
})
})
}
}
```
## `createContentLoader`
When building a content focused site, we often need to create an "archive" or "index" page: a page where we list all available entries in our content collection, for example blog posts or API pages. We **can** implement this directly with the data loader API, but since this is such a common use case, VitePress also provides a `createContentLoader` helper to simplify this:
```js
// posts.data.js
import { createContentLoader } from 'vitepress'
export default createContentLoader('posts/*.md', /* options */)
```
The helper takes a glob pattern relative to [project root](./routing#project-root), and returns a `{ watch, load }` data loader object that can be used as the default export in a data loader file. It also implements caching based on file modified timestamps to improve dev performance.
Note the loader only works with Markdown files - matched non-Markdown files will be skipped.
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
url: string
// frontmatter data of the page
frontmatter: Record<string, any>
// the following are only present if relevant options are enabled
// we will discuss them below
src: string | undefined
html: string | undefined
excerpt: string | undefined
}
```
By default, only `url` and `frontmatter` are provided. This is because the loaded data will be inlined as JSON in the client bundle, so we need to be cautious about its size. Here's an example using the data to build a minimal blog index page:
```vue
<script setup>
import { data as posts } from './posts.data.js'
</script>
<template>
<h1>All Blog Posts</h1>
<ul>
<li v-for="post of posts">
<a :href="post.url">{{ post.frontmatter.title }}</a>
<span>by {{ post.frontmatter.author }}</span>
</li>
</ul>
</template>
```
### Options
The default data may not suit all needs - you can opt-in to transform the data using options:
```js
// posts.data.js
import { createContentLoader } from 'vitepress'
export default createContentLoader('posts/*.md', {
includeSrc: true, // include raw markdown source?
render: true, // include rendered full page HTML?
excerpt: true, // include excerpt?
transform(rawData) {
// map, sort, or filter the raw data as you wish.
// the final result is what will be shipped to the client.
return rawData.sort((a, b) => {
return +new Date(b.frontmatter.date) - +new Date(a.frontmatter.date)
}).map(page => {
page.src // raw markdown source
page.html // rendered full page HTML
page.excerpt // rendered excerpt HTML (content above first `---`)
return {/* ... */}
})
}
})
```
Check out how it is used in the [Vue.js blog](https://github.com/vuejs/blog/blob/main/.vitepress/theme/posts.data.ts).
The `createContentLoader` API can also be used inside [build hooks](/reference/site-config#build-hooks):
```js
// .vitepress/config.js
export default {
async buildEnd() {
const posts = await createContentLoader('posts/*.md').load()
// generate files based on posts metadata, e.g. RSS feed
}
}
```

@ -1,9 +1,13 @@
---
outline: deep
---
# Deploy Your VitePress Site
The following guides are based on some shared assumptions:
- You are placing your docs inside the `docs` directory of your project.
- You are using the default build output location (`.vitepress/dist`).
- The VitePress site is inside the `docs` directory of your project.
- You are using the default build output directory (`.vitepress/dist`).
- VitePress is installed as a local dependency in your project, and you have set up the following scripts in your `package.json`:
```json
@ -15,31 +19,23 @@ The following guides are based on some shared assumptions:
}
```
::: tip
If your site is to be served at a subdirectory (`https://example.com/subdir/`), then you have to set `'/subdir/'` as the [`base`](/reference/site-config#base) in your `docs/.vitepress/config.js`.
**Example:** If you're using Github (or GitLab) Pages and deploying to `user.github.io/repo/`, then set your `base` to `/repo/`.
:::
## Build and Test Locally
- You may run this command to build the docs:
1. Run this command to build the docs:
```sh
$ npm run docs:build
```
- Once you've built the docs, you can test them locally by running:
2. Once built, preview it locally by running:
```sh
$ npm run docs:preview
```
The `preview` command will boot up a local static web server that will serve the files from `.vitepress/dist` at `http://localhost:4173`. It's an easy way to check if the production build looks fine in your local environment.
The `preview` command will boot up a local static web server that will serve the output directory `.vitepress/dist` at `http://localhost:4173`. You can use this to make sure everything looks good before pushing to production.
- You can configure the port of the server by passing `--port` as an argument.
3. You can configure the port of the server by passing `--port` as an argument.
```json
{
@ -49,23 +45,79 @@ If your site is to be served at a subdirectory (`https://example.com/subdir/`),
}
```
Now the `docs:preview` method will launch the server at `http://localhost:8080`.
Now the `docs:preview` method will launch the server at `http://localhost:8080`.
## Setting a Public Base Path
By default, we assume the site is going to be deployed at the root path of a domain (`/`). If your site is going to be served at a sub-path, e.g. `https://mywebsite.com/blog/`, then you need to set the [`base`](../reference/site-config#base) option to `'/blog/'` in the VitePress config.
**Example:** If you're using Github (or GitLab) Pages and deploying to `user.github.io/repo/`, then set your `base` to `/repo/`.
## HTTP Cache Headers
If you have control over the HTTP headers on your production server, you can configure `cache-control` headers to achieve better performance on repeated visits.
The production build uses hashed file names for static assets (JavaScript, CSS and other imported assets not in `public`). If you inspect the production preview using your browser devtools' network tab, you will see files like `app.4f283b18.js`.
This `4f283b18` hash is generated from the content of this file. The same hashed URL is guaranteed to serve the same file content - if the contents change, the URLs change too. This means you can safely use the strongest cache headers for these files. All such files will be placed under `assets/` in the output directory, so you can configure the following header for them:
```
Cache-Control: max-age=31536000,immutable
```
:::details Example Netlify `_headers` file
```
/assets/*
cache-control: max-age=31536000
cache-control: immutable
```
## Netlify, Vercel, AWS Amplify, Cloudflare Pages, Render
Note: the `_headers` file should be placed in the [public directory](/guide/asset-handling#the-public-directory) - in our case, `docs/public/_headers` - so that it is copied verbatim to the output directory.
[Netlify custom headers documentation](https://docs.netlify.com/routing/headers/)
:::
:::details Example Vercel config in `vercel.json`
```json
{
"headers": [
{
"source": "/assets/(.*)",
"headers": [
{
"key": "Cache-Control",
"value": "max-age=31536000, immutable"
}
]
}
]
}
```
Note: the `vercel.json` file should be placed at the root of your **repository**.
[Vercel documentation on headers config](https://vercel.com/docs/concepts/projects/project-configuration#headers)
:::
## Platform Guides
### Netlify / Vercel / Cloudflare Pages / AWS Amplify / Render
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:** `14` (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:** `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/))
::: 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.
:::
## GitHub Pages
### Using GitHub Actions
### GitHub Pages
1. In your theme config file, `docs/.vitepress/config.js`, set the `base` property to the name of your GitHub repository. If you plan to deploy your site to `https://foo.github.io/bar/`, then you should set base to `'/bar/'`. It should always start and end with a slash.
@ -95,7 +147,7 @@ Don't enable options like _Auto Minify_ for HTML code. It will remove comments f
with:
node-version: 16
cache: npm
- run: npm install --frozen-lockfile
- run: npm ci
- name: Build
run: npm run docs:build
- uses: actions/configure-pages@v2
@ -119,9 +171,7 @@ Don't enable options like _Auto Minify_ for HTML code. It will remove comments f
6. In your repository's Settings under Pages menu item, click `Visit site`, then you can see your site. Your docs will automatically deploy each time you push.
## GitLab Pages
### Using GitLab CI
### GitLab Pages
1. Set `outDir` in `docs/.vitepress/config.js` to `../public`.
@ -164,7 +214,7 @@ Don't enable options like _Auto Minify_ for HTML code. It will remove comments f
- main
```
## Azure Static Web Apps
### Azure Static Web Apps
1. Follow the [official documentation](https://docs.microsoft.com/en-us/azure/static-web-apps/build-configuration).
@ -174,7 +224,7 @@ Don't enable options like _Auto Minify_ for HTML code. It will remove comments f
- **`output_location`**: `docs/.vitepress/dist`
- **`app_build_command`**: `npm run docs:build`
## Firebase
### Firebase
1. Create `firebase.json` and `.firebaserc` at the root of your project:
@ -205,7 +255,7 @@ Don't enable options like _Auto Minify_ for HTML code. It will remove comments f
firebase deploy
```
## Surge
### Surge
1. After running `npm run docs:build`, run this command to deploy:
@ -213,7 +263,7 @@ Don't enable options like _Auto Minify_ for HTML code. It will remove comments f
npx surge docs/.vitepress/dist
```
## Heroku
### Heroku
1. Follow documentation and guide given in [`heroku-buildpack-static`](https://elements.heroku.com/buildpacks/heroku/heroku-buildpack-static).
@ -225,6 +275,6 @@ Don't enable options like _Auto Minify_ for HTML code. It will remove comments f
}
```
## Edgio
### Edgio
Refer [Creating and Deploying a VitePress App To Edgio](https://docs.edg.io/guides/vitepress).

@ -1,6 +1,6 @@
# 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.
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.
However, there are a number of cases where configuration alone won't be enough. For example:
@ -36,6 +36,58 @@ export default DefaultTheme
See [default theme CSS variables](https://github.com/vuejs/vitepress/blob/main/src/client/theme-default/styles/vars.css) that can be overridden.
## Using Different Fonts
VitePress uses [Inter](https://rsms.me/inter/) as the default font, and will include the fonts in the build output. The font is also auto preloaded in production. However, this may not be desirable if you want to use a different main font.
To avoid including Inter in the build output, import the theme from `vitepress/theme-without-fonts` instead:
```js
// .vitepress/theme/index.js
import DefaultTheme from 'vitepress/theme-without-fonts'
import './my-fonts.css'
export default DefaultTheme
```
```css
/* .vitepress/theme/custom.css */
:root {
--vp-font-family-base: /* normal text font */
--vp-font-family-mono: /* code font */
}
```
:::warning
If you are using optional components like the [Team Page](/reference/default-theme-team-page) components, make sure to also import them from `vitepress/theme-without-fonts`!
:::
If your font is a local file referenced via `@font-face`, it will be processed as an asset and included under `.vitepress/dist/assets` with hashed filename. To preload this file, use the [transformHead](/reference/site-config#transformhead) build hook:
```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: ''
}
]
]
}
}
}
```
## Registering Global Components
```js
@ -137,3 +189,29 @@ Full list of slots available in the default theme layout:
- `nav-bar-content-after`
- `nav-screen-content-before`
- `nav-screen-content-after`
## 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:
```ts
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)
)
}
]
}
}
})
```
To know the exact name of the component refer [our source code](https://github.com/vuejs/vitepress/tree/main/src/client/theme-default/components). Since the components are internal, there is a slight chance their name is updated between minor releases.

@ -11,7 +11,7 @@ editLink: true
---
```
Many site or default theme config options have corresponding options in frontmatter. You can use frontmatter to override specific behavior for the current page only. For details, see [Frontmatter Config Reference](/reference/frontmatter-config).
Many site or default theme config options have corresponding options in frontmatter. You can use frontmatter to override specific behavior for the current page only. For details, see [Frontmatter Config Reference](../reference/frontmatter-config).
You can also define custom frontmatter data of your own, to be used in dynamic Vue expressions on the page.
@ -32,7 +32,7 @@ editLink: true
Guide content
```
You can also access current page's frontmatter data in `<script setup>` with the [`useData()`](/reference/runtime-api#usedata) helper.
You can also access current page's frontmatter data in `<script setup>` with the [`useData()`](../reference/runtime-api#usedata) helper.
## Alternative Frontmatter Formats

@ -92,7 +92,7 @@ Assuming you chose to scaffold the VitePress project in `./docs`, the generated
The `docs` directory is considered the **project root** of the VitePress site. The `.vitepress` directory is a reserved location for VitePress' config file, dev server cache, build output, and optional theme customization code.
:::tip
By default, VitePress stores its dev server cache in `.vitepress/cache`, and the production build output in `.vitepress/dist`. If using Git, you should add them to your `.gitignore` file. These locations can also be [configured](/reference/site-config#outdir).
By default, VitePress stores its dev server cache in `.vitepress/cache`, and the production build output in `.vitepress/dist`. If using Git, you should add them to your `.gitignore` file. These locations can also be [configured](../reference/site-config#outdir).
:::
### The Config File
@ -112,7 +112,7 @@ export default {
}
```
You can also configure the behavior of the theme via the `themeConfig` option. Consult the [Config Reference](/reference/site-config) for full details on all config options.
You can also configure the behavior of the theme via the `themeConfig` option. Consult the [Config Reference](../reference/site-config) for full details on all config options.
### Source Files
@ -170,17 +170,17 @@ $ pnpm exec vitepress dev docs
:::
More command line usage is documented in the [CLI Reference](/reference/cli).
More command line usage is documented in the [CLI Reference](../reference/cli).
The dev server should be running at `http://localhost:5173`. Visit the URL in your browser to see your new site in action!
## What's Next?
- To better understand how markdown files are mapped to generated HTML, proceed to the [Routing Guide](./routing.md).
- To better understand how markdown files are mapped to generated HTML, proceed to the [Routing Guide](./routing).
- To discover more about what you can do on the page, such as writing markdown content or using Vue Component, refer to the "Writing" section of the guide. A great place to start would be to learn about [Markdown Extensions](/guide/markdown).
- To discover more about what you can do on the page, such as writing markdown content or using Vue Component, refer to the "Writing" section of the guide. A great place to start would be to learn about [Markdown Extensions](./markdown).
- To explore the features provided by the default documentation theme, check out the [Default Theme Config Reference](/reference/default-theme-config).
- To explore the features provided by the default documentation theme, check out the [Default Theme Config Reference](../reference/default-theme-config).
- If you want to further customize the appearance of your site, explore how to either [Extend the Default Theme](./extending-default-theme) or [Build a Custom Theme](./custom-theme).

@ -49,7 +49,7 @@ interface LocaleSpecificConfig<ThemeConfig = any> {
}
```
Refer [`DefaultTheme.Config`](https://github.com/vuejs/vitepress/blob/main/types/default-theme.d.ts) interface for details on customizing the placeholder texts of the default theme. Don't override `themeConfig.algolia` or `themeConfig.carbonAds` at locale-level. Refer [Algolia docs](/reference/default-theme-search#i18n) for using multilingual search.
Refer [`DefaultTheme.Config`](https://github.com/vuejs/vitepress/blob/main/types/default-theme.d.ts) interface for details on customizing the placeholder texts of the default theme. Don't override `themeConfig.algolia` or `themeConfig.carbonAds` at locale-level. Refer [Algolia docs](../reference/default-theme-search#i18n) for using multilingual search.
**Pro tip:** Config file can be stored at `docs/.vitepress/config/index.ts` too. It might help you organize stuff by creating a configuration file per locale and then merge and export them from `index.ts`.

@ -64,7 +64,7 @@ lang: en-US
This data will be available to the rest of the page, along with all custom and theming components.
For more details, see [Frontmatter](/reference/frontmatter-config).
For more details, see [Frontmatter](../reference/frontmatter-config).
## GitHub-Style Tables
@ -281,7 +281,7 @@ export default {
A [list of valid languages](https://github.com/shikijs/shiki/blob/main/docs/languages.md) is available on Shiki's repository.
You may also customize syntax highlight theme in app config. Please see [`markdown` options](/reference/site-config#markdown) for more details.
You may also customize syntax highlight theme in app config. Please see [`markdown` options](../reference/site-config#markdown) for more details.
## Line Highlighting in Code Blocks
@ -493,7 +493,7 @@ export default {
}
```
Please see [`markdown` options](/reference/site-config#markdown) for more details.
Please see [`markdown` options](../reference/site-config#markdown) for more details.
You can add `:line-numbers` / `:no-line-numbers` mark in your fenced code blocks to override the value set in config.
@ -748,4 +748,4 @@ module.exports = {
}
```
See full list of configurable properties in [Config Reference: App Config](/reference/site-config#markdown).
See full list of configurable properties in [Config Reference: App Config](../reference/site-config#markdown).

@ -12,12 +12,12 @@ If you're coming from VitePress 0.x version, there're several breaking changes d
- `children` key is now named `items`.
- Top level item may not contain `link` at the moment. We're planning to bring it back.
- `repo`, `repoLabel`, `docsDir`, `docsBranch`, `editLinks`, `editLinkText` are removed in favor of more flexible api.
- For adding GitHub link with icon to the nav, use [Social Links](/reference/default-theme-nav#navigation-links) feature.
- For adding "Edit this page" feature, use [Edit Link](/reference/default-theme-edit-link) feature.
- For adding GitHub link with icon to the nav, use [Social Links](../reference/default-theme-nav#navigation-links) feature.
- For adding "Edit this page" feature, use [Edit Link](../reference/default-theme-edit-link) feature.
- `lastUpdated` option is now split into `config.lastUpdated` and `themeConfig.lastUpdatedText`.
- `carbonAds.carbon` is changed to `carbonAds.code`.
## Frontmatter Config
- `home: true` option has changed to `layout: home`. Also, many Homepage related settings have been modified to provide additional features. See [Home Page guide](/reference/default-theme-home-page) for details.
- `footer` option is moved to [`themeConfig.footer`](/reference/default-theme-config#footer).
- `home: true` option has changed to `layout: home`. Also, many Homepage related settings have been modified to provide additional features. See [Home Page guide](../reference/default-theme-home-page) for details.
- `footer` option is moved to [`themeConfig.footer`](../reference/default-theme-config#footer).

@ -6,7 +6,7 @@ In MPA mode, all pages are rendered without any JavaScript included by default.
However, due to the absence of SPA navigation, cross-page links will lead to full page reloads. Post-load navigations in MPA mode will not feel as instant as in SPA mode.
Also note that no-JS-by-default also means you are essentially using Vue purely as a server-side templating language - no event handlers will be attached in the browser, so there will be no interactivity. To load client-side JavaScript, you can do so by using the special `<script client>` tag (works in both `.md` and `.vue` files, but only in MPA mode):
Also note that no-JS-by-default means you are essentially using Vue purely as a server-side templating language. No event handlers will be attached in the browser, so there will be no interactivity. To load client-side JavaScript, you will need to use the special `<script client>` tag:
```html
<script client>
@ -18,6 +18,6 @@ document.querySelector('h1').addEventListener('click', () => {
# Hello
```
Client scripts in all theme components will be bundled together, while client script for a specific page will be split for that page only.
`<script client>` is a VitePress-only feature, not a Vue feature. It works in both `.md` and `.vue` files, but only in MPA mode. Client scripts in all theme components will be bundled together, while client script for a specific page will be split for that page only.
Notice that `<script client>` is **not evaluated as Vue component code**: it's processed as a plain JavaScript module. For this reason, MPA mode should only be used if your site requires absolutely minimal client-side interactivity.
Note that `<script client>` is **not evaluated as Vue component code**: it's processed as a plain JavaScript module. For this reason, MPA mode should only be used if your site requires absolutely minimal client-side interactivity.

@ -60,7 +60,7 @@ docs/getting-started.md --> /getting-started.html
### Source Directory
Source directory is where your Markdown source files live. By default, it is the same as the project root. However, you can configure it via the [`srcDir`](/reference/site-config#srcdir) config option.
Source directory is where your Markdown source files live. By default, it is the same as the project root. However, you can configure it via the [`srcDir`](../reference/site-config#srcdir) config option.
The `srcDir` option is resolved relative to project root. For example, with `srcDir: 'src'`, your file structure will look like this:
@ -85,21 +85,35 @@ You can use both absolute and relative paths when linking between pages. Note th
```md
<!-- Do -->
[Getting Started](/guide/getting-started)
[Getting Started](./getting-started)
[Getting Started](../guide/getting-started)
<!-- Don't -->
[Getting Started](/guide/getting-started.md)
[Getting Started](/guide/getting-started.html)
[Getting Started](./getting-started.md)
[Getting Started](./getting-started.html)
```
Learn more about linking to assets such images in [Asset Handling](asset-handling).
## Generating Clean URL
:::warning Server Support Required
To serve clean URLs with VitePress, server-side support is required.
:::
By default, VitePress resolves inbound links to URLs ending with `.html`. However, some users may prefer "Clean URLs" without the `.html` extension - for example, `example.com/path` instead of `example.com/path.html`.
One way to achieve clean URLs is to structure your files using only `index.md` inside directories:
Some servers or hosting platforms (for example Netlify or Vercel) provide the ability to map a URL like `/foo` to `/foo.html` if it exists, without a redirect:
- Netlify supports this by default.
- Vercel requires enabling the [`cleanUrls` option in `vercel.json`](https://vercel.com/docs/concepts/projects/project-configuration#cleanurls).
If this feature is available to you, you can then also enable VitePress' own [`cleanUrls`](../reference/site-config#cleanurls) config option so that:
- Inbound links between pages are generated without the `.html` extension.
- If current path ends with `.html`, the router will perform a client-side redirect to the extension-less path.
If, however, you cannot configure your server with such support (e.g. GitHub pages), you will have to manually resort to the following directory structure:
```
.
@ -110,8 +124,6 @@ One way to achieve clean URLs is to structure your files using only `index.md` i
└─ index.md
```
Some servers or hosting platforms (for example Netlify or Vercel) provide the ability to map a URL like `/foo` to `/foo.html` if it exists. If this feature is available to you, you can use the [`cleanUrls`](/reference/site-config#cleanurls) config option so that inbound links are always generated without the `.html` extension. When this option is enabled, VitePress' client-side router will also redirect to the clean URL when a visited URL ends with `.html`.
## Route Rewrites
You can customize the mapping between the source directory structure and the generated pages. It's useful when you have a complex project structure. For example, let's say you have a monorepo with multiple packages, and would like to place documentations along with the source files like this:
@ -136,7 +148,7 @@ packages/pkg-a/src/pkg-a-docs.md --> /pkg-a/index.html
packages/pkg-b/src/pkg-b-docs.md --> /pkg-b/index.html
```
You can achieve this by configuring the [`rewrites`](/reference/site-config#rewrites) option like this:
You can achieve this by configuring the [`rewrites`](../reference/site-config#rewrites) option like this:
```ts
// .vitepress/config.js
@ -294,7 +306,7 @@ You can use the params to pass additional data to each page. The Markdown route
- version: {{ $params.version }}
```
You can also access the current page's params via the `[useData](/reference/runtime-api#usedata)` runtime API. This is available in both Markdown files and Vue components:
You can also access the current page's params via the `[useData](../reference/runtime-api#usedata)` runtime API. This is available in both Markdown files and Vue components:
```vue
<script setup>

@ -0,0 +1,84 @@
---
outline: deep
---
# SSR Compatibility
VitePress pre-renders the app in Node.js during the production build, using Vue's Server-Side Rendering (SSR) capabilities. This means all custom code in theme components are subject to SSR Compatibility.
The [SSR section in official Vue docs](https://vuejs.org/guide/scaling-up/ssr.html) provides more context on what is SSR, the relationship between SSR / SSG, and common notes on writing SSR-friendly code. The rule of thumb is to only access browser / DOM APIs in `beforeMount` or `mounted` hooks of Vue components.
## `<ClientOnly>`
If you are using or demoing components that are not SSR-friendly (for example, contain custom directives), you can wrap them inside the built-in `<ClientOnly>` component:
```md
<ClientOnly>
<NonSSRFriendlyComponent />
</ClientOnly>
```
## Libraries that Access Browser API on Import
Some components or libraries access browser APIs **on import**. To use code that assumes a browser environment on import, you need to dynamically import them.
### Importing in Mounted Hook
```vue
<script setup>
import { onMounted } from 'vue'
onMounted(() => {
import('./lib-that-access-window-on-import').then((module) => {
// use code
})
})
</script>
```
### Conditional Import
You can also conditionally import a dependency using the `import.meta.env.SSR` flag (part of [Vite env variables](https://vitejs.dev/guide/env-and-mode.html#env-variables)):
```js
if (!import.meta.env.SSR) {
import('./lib-that-access-window-on-import').then((module) => {
// use code
})
}
```
Since [`Theme.enhanceApp`](/guide/custom-theme#theme-interface) can be async, you can conditionally import and register Vue plugins that access browser APIs on import:
```js
// .vitepress/theme/index.js
export default {
// ...
async enhanceApp({ app }) {
if (!import.meta.env.SSR) {
const plugin = await import('plugin-that-access-window-on-import')
app.use(plugin)
}
}
}
```
### `defineClientComponent`
VitePress provides a convenience helper for importing Vue components that access browser APIs on import.
```vue
<script setup>
import { defineClientComponent } from 'vitepress'
const ClientComp = defineClientComponent(() => {
return import('component-that-access-window-on-import')
})
</script>
<template>
<ClientComp />
</template>
```
The target component will only be imported in the mounted hook of the wrapper component.

@ -4,6 +4,10 @@ In VitePress, each Markdown file is compiled into HTML and then processed as a [
It's worth noting that VitePress leverages Vue's compiler to automatically detect and optimize the purely static parts of the Markdown content. Static contents are optimized into single placeholder nodes and eliminated from the page's JavaScript payload for initial visits. They are also skipped during client-side hydration. In short, you only pay for the dynamic parts on any given page.
:::tip SSR Compatibility
All Vue usage needs to be SSR-compatible. See [SSR Compatibility](./ssr-compat) for details and common workarounds.
:::
## Templating
### Interpolation
@ -53,7 +57,7 @@ const count = ref(0)
The count is: {{ count }}
<button :class="$style.module" @click="count++">Increment</button>
<button :class="$style.button" @click="count++">Increment</button>
<style module>
.button {
@ -67,7 +71,7 @@ The count is: {{ count }}
When used in Markdown, `<style scoped>` requires adding special attributes to every element on the current page, which will significantly bloat the page size. `<style module>` is preferred when locally-scoped styling is needed in a page.
:::
You also have access to VitePress' runtime APIs such as the [`useData` helper](/reference/runtime-api#usedata), which provides access to current page's metadata:
You also have access to VitePress' runtime APIs such as the [`useData` helper](../reference/runtime-api#usedata), which provides access to current page's metadata:
**Input**
@ -102,7 +106,7 @@ If a component is only used by a few pages, it's recommended to explicitly impor
```md
<script setup>
import CustomComponent from '../../components/CustomComponent.vue'
import CustomComponent from '../components/CustomComponent.vue'
</script>
# Docs
@ -118,7 +122,7 @@ This is a .md using a custom component
### Registering Components Globally
If a component is going to be used on most of the pages, they can be registered globally by customizing the Vue app instance. See relevant section in [Extending Default Theme](/guide/extending-default-theme#registering-global-components) for an example.
If a component is going to be used on most of the pages, they can be registered globally by customizing the Vue app instance. See relevant section in [Extending Default Theme](./extending-default-theme#registering-global-components) for an example.
::: warning IMPORTANT
Make sure a custom component's name either contains a hyphen or is in PascalCase. Otherwise, it will be treated as an inline element and wrapped inside a `<p>` tag, which will lead to hydration mismatch because `<p>` does not allow block elements to be placed inside it.
@ -216,66 +220,9 @@ Then you can use the following in Markdown and theme components:
</style>
```
## Browser API Access Restrictions
Because VitePress applications are server-rendered in Node.js when generating static builds, any Vue usage must conform to the [universal code requirements](https://vuejs.org/guide/scaling-up/ssr.html). In short, make sure to only access Browser / DOM APIs in `beforeMount` or `mounted` hooks.
If you are using or demoing components that are not SSR-friendly (for example, contain custom directives), you can wrap them inside the built-in `<ClientOnly>` component:
```md
<ClientOnly>
<NonSSRFriendlyComponent />
</ClientOnly>
```
Note this does not fix components or libraries that access Browser APIs **on import**. To use code that assumes a browser environment on import, you need to dynamically import them in proper lifecycle hooks:
```vue
<script>
export default {
mounted() {
import('./lib-that-access-window-on-import').then((module) => {
// use code
})
}
}
</script>
```
If your module `export default` a Vue component, you can register it dynamically:
```vue
<template>
<component
v-if="dynamicComponent"
:is="dynamicComponent">
</component>
</template>
<script>
export default {
data() {
return {
dynamicComponent: null
}
},
mounted() {
import('./lib-that-access-window-on-import').then((module) => {
this.dynamicComponent = module.default
})
}
}
</script>
```
**Also see:**
- [Vue.js > Dynamic Components](https://vuejs.org/guide/essentials/component-basics.html#dynamic-components)
## Using Teleports
Vitepress currently has SSG support for teleports to body only. For other targets, you can wrap them inside the built-in `<ClientOnly>` component or inject the teleport markup into the correct location in your final page HTML through [`postRender` hook](/reference/site-config#postrender).
Vitepress currently has SSG support for teleports to body only. For other targets, you can wrap them inside the built-in `<ClientOnly>` component or inject the teleport markup into the correct location in your final page HTML through [`postRender` hook](../reference/site-config#postrender).
<ModalDemo />
@ -294,7 +241,7 @@ Vitepress currently has SSG support for teleports to body only. For other target
```
<script setup>
import ModalDemo from '../../components/ModalDemo.vue'
import ModalDemo from '../components/ModalDemo.vue'
</script>
<style>

@ -18,7 +18,7 @@ Just want to try it out? Skip to the [Quickstart](./getting-started).
- **Blogs, Portfolios, and Marketing Sites**
VitePress supports [fully customized themes](/guide/custom-theme), with the developer experience of a standard Vite + Vue application. Being built on Vite also means you can directly leverage Vite plugins from its rich ecosystem. In addition, VitePress provides flexible APIs to [load data](/guide/data-loading) (local or remote) and [dynamically generate routes](/guide/routing#dynamic-routes). You can use it to build almost anything as long as the data can be determined at build time.
VitePress supports [fully customized themes](./custom-theme), with the developer experience of a standard Vite + Vue application. Being built on Vite also means you can directly leverage Vite plugins from its rich ecosystem. In addition, VitePress provides flexible APIs to [load data](./data-loading) (local or remote) and [dynamically generate routes](./routing#dynamic-routes). You can use it to build almost anything as long as the data can be determined at build time.
The official [Vue.js blog](https://blog.vuejs.org/) is a simple blog that generates its index page based on local content.
@ -28,9 +28,9 @@ VitePress aims to provide a great Developer Experience (DX) when working with Ma
- **[Vite-Powered:](https://vitejs.dev/)** instant server start, with edits always instantly reflected (<100ms) without page reload.
- **[Built-in Markdown Extensions:](/guide/markdown)** Frontmatter, tables, syntax highlighting... you name it. Specifically, VitePress provides many advanced features for working with code blocks, making it ideal for highly technical documentation.
- **[Built-in Markdown Extensions:](./markdown)** Frontmatter, tables, syntax highlighting... you name it. Specifically, VitePress provides many advanced features for working with code blocks, making it ideal for highly technical documentation.
- **[Vue-Enhanced Markdown](/guide/using-vue):** each Markdown page is also a Vue [Single-File Component](https://vuejs.org/guide/scaling-up/sfc.html), thanks to Vue template's 100% syntax compatibility with HTML. You can embed interactivity in your static content using Vue templating features or imported Vue components.
- **[Vue-Enhanced Markdown](./using-vue):** each Markdown page is also a Vue [Single-File Component](https://vuejs.org/guide/scaling-up/sfc.html), thanks to Vue template's 100% syntax compatibility with HTML. You can embed interactivity in your static content using Vue templating features or imported Vue components.
## Performance

@ -39,7 +39,7 @@ vitepress build [root]
| Option | Description |
| - | - |
| `--mpa` (experimental) | Build in [MPA mode](/guide/mpa-mode) without client-side hydration (`boolean`) |
| `--mpa` (experimental) | Build in [MPA mode](../guide/mpa-mode) without client-side hydration (`boolean`) |
| `--base <path>` | Public base path (default: `/`) (`string`) |
| `--target <target>` | Transpile target (default: `"modules"`) (`string`) |
| `--outDir <dir>` | Output directory (default: `.vitepress/dist`) (`string`) |
@ -65,7 +65,7 @@ vitepress preview [root]
## `vitepress init`
Start the [Setup Wizard](/guide/getting-started#setup-wizard) in current directory.
Start the [Setup Wizard](../guide/getting-started#setup-wizard) in current directory.
### Usage

@ -168,6 +168,7 @@ export type SidebarItem = {
- Type: `boolean`
- Default: `true`
- Can be overridden per page via [frontmatter](./frontmatter-config#aside)
Setting this value to `false` prevents rendering of aside container.
@ -175,16 +176,10 @@ Setting this value to `false` prevents rendering of aside container.
- 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.
## outlineBadges
- Type: `boolean`
- Default: `true`
By default the badge text is displayed in the outline. Disable this to hide badge text from outline.
## outlineTitle
- Type: `string`
@ -270,6 +265,7 @@ export interface Footer {
## editLink
- Type: `EditLink`
- Can be overridden per page via [frontmatter](./frontmatter-config#editlink)
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.
@ -320,7 +316,7 @@ export interface AlgoliaSearchOptions extends DocSearchProps {
View full options [here](https://github.com/vuejs/vitepress/blob/main/types/docsearch.d.ts).
## carbonAds
## carbonAds {#carbon-ads}
- Type: `CarbonAdsOptions`

@ -1,5 +1,7 @@
# Edit Link
## Site-Level Config
Edit Link lets you display a link to edit the page on Git management services such as GitHub, or GitLab. To enable it, add `themeConfig.editLink` options to your config.
```js
@ -14,6 +16,26 @@ export default {
The `pattern` option defines the URL structure for the link, and `:path` is going to be replaced with the page path.
You can also put a pure function that accepts `relativePath` as the argument and returns the URL string.
```js
export default {
themeConfig: {
editLink: {
pattern: ({ relativePath }) => {
if (relativePath.startsWith('packages/')) {
return `https://github.com/acme/monorepo/edit/main/${relativePath}`
} else {
return `https://github.com/acme/monorepo/edit/main/docs/${relativePath}`
}
}
}
}
}
```
It should not have side-effects nor access anything outside of its scope since it will be serialized and executed in the browser.
By default, this will add the link text "Edit this page" at the bottom of the doc page. You may customize this text by defining the `text` option.
```js
@ -26,3 +48,13 @@ export default {
}
}
```
## Frontmatter Config
This can be disabled per-page using the `editLink` option on frontmatter:
```yaml
---
lastUpdated: false
---
```

@ -36,4 +36,4 @@ export default {
}
```
Note that footer will not be displayed when the [SideBar](/reference/default-theme-sidebar) is visible.
Note that footer will not be displayed when the [SideBar](./default-theme-sidebar) is visible.

@ -1,11 +1,8 @@
# Last Updated
The update time of the last content will be displayed in the lower right corner of the page.
To enable it, add `lastUpdated` options to your config.
The update time of the last content will be displayed in the lower right corner of the page. To enable it, add `lastUpdated` options to your config.
## Page Configuration
Add `lastUpdated` options to your config.
## Site-Level Config
```js
export default {
@ -13,9 +10,9 @@ export default {
}
```
## Frontmatter Configuration
## Frontmatter Config
If you would like to hide the last update text, set false to the `lastUpdated` option.
This can be disabled per-page using the `lastUpdated` option on frontmatter:
```yaml
---

@ -23,7 +23,7 @@ It also provides documentation specific features listed below. These features ar
## Page Layout
Option `page` is treated as "blank page". The Markdown will still be parsed, and all of the [Markdown Extensions](/guide/markdown) work as same as `doc` layout, but it wouldn't get any default stylings.
Option `page` is treated as "blank page". The Markdown will still be parsed, and all of the [Markdown Extensions](../guide/markdown) work as same as `doc` layout, but it wouldn't get any default stylings.
The page layout will let you style everything by you without VitePress theme affecting the markup. This is useful when you want to create your own custom page.
@ -31,7 +31,7 @@ Note that even in this layout, sidebar will still show up if the page has a matc
## Home Layout
Option `home` will generate templated "Homepage". In this layout, you can set extra options such as `hero` and `features` to customize the content further. Please visit [Default Theme: Home Page](/reference/default-theme-home-page) for more details.
Option `home` will generate templated "Homepage". In this layout, you can set extra options such as `hero` and `features` to customize the content further. Please visit [Default Theme: Home Page](./default-theme-home-page) for more details.
## No Layout

@ -4,7 +4,7 @@ The Nav is the navigation bar displayed on top of the page. It contains the site
## Site Title and Logo
By default, nav shows the title of the site referencing [`config.title`](/reference/site-config#title) value. If you would like to change what's displayed on nav, you may define custom text in `themeConfig.siteTitle` option.
By default, nav shows the title of the site referencing [`config.title`](./site-config#title) value. If you would like to change what's displayed on nav, you may define custom text in `themeConfig.siteTitle` option.
```js
export default {
@ -35,7 +35,7 @@ export default {
}
```
You can also pass an object as logo if you want to add `alt` attribute or customize it based on dark/light mode. Refer [`themeConfig.logo`](/reference/default-theme-config#logo) for details.
You can also pass an object as logo if you want to add `alt` attribute or customize it based on dark/light mode. Refer [`themeConfig.logo`](./default-theme-config#logo) for details.
## Navigation Links
@ -159,4 +159,4 @@ export default {
## Social Links
Refer [`socialLinks`](/reference/default-theme-config#sociallinks).
Refer [`socialLinks`](./default-theme-config#sociallinks).

@ -1,6 +1,6 @@
# Sidebar
The sidebar is the main navigation block for your documentation. You can configure the sidebar menu in [`themeConfig.sidebar`](/reference/default-theme-config#sidebar).
The sidebar is the main navigation block for your documentation. You can configure the sidebar menu in [`themeConfig.sidebar`](./default-theme-config#sidebar).
```js
export default {

@ -68,7 +68,7 @@ If you have large number of members, or simply would like to have more space to
## Create a full Team Page
Instead of adding team members to doc page, you may also create a full Team Page, similar to how you can create a custom [Home Page](/reference/default-theme-home-page).
Instead of adding team members to doc page, you may also create a full Team Page, similar to how you can create a custom [Home Page](./default-theme-home-page).
To create a team page, first, create a new md file. The file name doesn't matter, but here lets call it `team.md`. In this file, set frontmatter option `layout: page`, and then you may compose your page structure using `TeamPage` components.

@ -25,7 +25,7 @@ You can access frontmatter data via the `$frontmatter` global in Vue expressions
- Type: `string`
Title for the page. It's same as [config.title](/reference/site-config#title), and it overrides the site-level config.
Title for the page. It's same as [config.title](./site-config#title), and it overrides the site-level config.
```yaml
---
@ -37,7 +37,7 @@ title: VitePress
- Type: `string | boolean`
The suffix for the title. It's same as [config.titleTemplate](/reference/site-config#titletemplate), and it overrides the site-level config.
The suffix for the title. It's same as [config.titleTemplate](./site-config#titletemplate), and it overrides the site-level config.
```yaml
---
@ -50,7 +50,7 @@ titleTemplate: Vite & Vue powered static site generator
- Type: `string`
Description for the page. It's same as [config.description](/reference/site-config#description), and it overrides the site-level config.
Description for the page. It's same as [config.description](./site-config#description), and it overrides the site-level config.
```yaml
---
@ -105,11 +105,11 @@ layout: doc
### hero <Badge type="info" text="default theme only" /> <Badge type="info" text="Home page only" />
Defines contents of home hero section when `layout` is set to `home`. More details in [Default Theme: Home Page](/reference/default-theme-home-page).
Defines contents of home hero section when `layout` is set to `home`. More details in [Default Theme: Home Page](./default-theme-home-page).
### features <Badge type="info" text="default theme only" /> <Badge type="info" text="Home page only" />
Defines items to display in features section when `layout` is set to `home`. More details in [Default Theme: Home Page](/reference/default-theme-home-page).
Defines items to display in features section when `layout` is set to `home`. More details in [Default Theme: Home Page](./default-theme-home-page).
### aside <Badge type="info" text="default theme only" />
@ -129,17 +129,30 @@ 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](/reference/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](./default-theme-config#outline), and it overrides the theme config.
### lastUpdated <Badge type="info" text="default theme only" />
- Type: `boolean`
- Default: `true`
Whether to display [Last Updated](/reference/default-theme-last-updated) text in the current page.
Whether to display [Last Updated](./default-theme-last-updated) text in the footer of the current page.
```yaml
---
lastUpdated: false
---
```
### editLink <Badge type="info" text="default theme only" />
- Type: `boolean`
- Default: `true`
Whether to display [Edit Link](./default-theme-edit-link) in the footer of the current page.
```yaml
---
editLink: false
---
```

@ -94,11 +94,11 @@ interface Router {
- **Type**: `(path: string) => string`
Appends the configured [`base`](/reference/site-config#base) to a given URL path. Also see [Base URL](/guide/asset-handling#base-url).
Appends the configured [`base`](./site-config#base) to a given URL path. Also see [Base URL](../guide/asset-handling#base-url).
## `<Content />` <Badge type="info" text="component" />
The `<Content />` component displays the rendered markdown contents. Useful [when creating your own theme](/guide/custom-theme).
The `<Content />` component displays the rendered markdown contents. Useful [when creating your own theme](../guide/custom-theme).
```vue
<template>
@ -121,9 +121,11 @@ If you are using or demoing components that are not SSR-friendly (for example, c
</ClientOnly>
```
- Related: [SSR Compatibility](/guide/ssr-compat)
## `$frontmatter` <Badge type="info" text="template global" />
Directly access current page's [frontmatter](/guide/frontmatter) data in Vue expressions.
Directly access current page's [frontmatter](../guide/frontmatter) data in Vue expressions.
```md
---
@ -135,7 +137,7 @@ title: Hello
## `$params` <Badge type="info" text="template global" />
Directly access current page's [dynamic route params](/guide/routing#dynamic-routes) in Vue expressions.
Directly access current page's [dynamic route params](../guide/routing#dynamic-routes) in Vue expressions.
```md
- package name: {{ $params.pkg }}

@ -6,25 +6,11 @@ outline: deep
Site config is where you can define the global settings of the site. App config options define settings that apply to every VitePress site, regardless of what theme it is using. For example, the base directory or the title of the site.
<div class="site-config-toc">
[[toc]]
</div>
<style>
@media (min-width: 1280px) {
.site-config-toc {
display: none;
}
}
</style>
## Overview
### 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`, `.cjs`, `.mjs`, `.cts`, and `.mts`.
It is recommended to use ES modules syntax in config files. The config file should default export an object:
@ -77,6 +63,20 @@ export default defineConfigWithTheme<ThemeConfig>({
})
```
### Vite, Vue & Markdown Config
- **Vite**
You can configure the underlying Vite instance using the [vite](#vite) option in your VitePress config. No need to create a separate Vite config file.
- **Vue**
VitePress already includes the official Vue plugin for Vite ([@vitejs/plugin-vue](https://github.com/vitejs/vite-plugin-vue)). You can configure its options using the [vue](#vue) option in your VitePress config.
- **Markdown**
You can configure the underlying [Markdown-It](https://github.com/markdown-it/markdown-it) instance using the [markdown](#markdown) option in your VitePress config.
## Site Metadata
### title
@ -206,7 +206,7 @@ export default {
- Type: `boolean`
- Default: `false`
When set to `true`, VitePress will remove the trailing `.html` from URLs. Also see [Generating Clean URL](/guide/routing#generating-clean-url).
When set to `true`, VitePress will remove the trailing `.html` from URLs. Also see [Generating Clean URL](../guide/routing#generating-clean-url).
::: warning Server Support Required
Enabling this may require additional configuration on your hosting platform. For it to work, your server must be able to serve `/foo.html` when visiting `/foo` **without a redirect**.
@ -216,7 +216,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 <-> URL mappings. See [Routing: Route Rewrites](../guide/routing#route-rewrites) for more details.
```ts
export default {
@ -233,7 +233,7 @@ export default {
- Type: `string`
- Default: `.`
The directory where your markdown pages are stored, relative to project root. Also see [Root and Source Directory](/guide/routing#root-and-source-directory).
The directory where your markdown pages are stored, relative to project root. Also see [Root and Source Directory](../guide/routing#root-and-source-directory).
```ts
export default {
@ -259,7 +259,7 @@ export default {
- Type: `string`
- Default: `./.vitepress/dist`
The build output location for the site, relative to [project root](/guide/routing#root-and-source-directory).
The build output location for the site, relative to [project root](../guide/routing#root-and-source-directory).
```ts
export default {
@ -272,7 +272,7 @@ export default {
- Type: `string`
- Default: `./.vitepress/cache`
The directory for cache files, relative to [project root](/guide/routing#root-and-source-directory). See also: [cacheDir](https://vitejs.dev/config/shared-options.html#cachedir).
The directory for cache files, relative to [project root](../guide/routing#root-and-source-directory). See also: [cacheDir](https://vitejs.dev/config/shared-options.html#cachedir).
```ts
export default {
@ -298,7 +298,7 @@ export default {
- Type: `boolean`
- Default: `false`
When set to `true`, the production app will be built in [MAP Mode](/guide/mpa-mode). MPA mode ships 0kb JavaScript by default, at the cost of disabling client-side navigation and requires explicit opt-in for interactivity.
When set to `true`, the production app will be built in [MAP Mode](../guide/mpa-mode). MPA mode ships 0kb JavaScript by default, at the cost of disabling client-side navigation and requires explicit opt-in for interactivity.
## Theming
@ -320,7 +320,7 @@ This option injects an inline script that restores users settings from local sto
- Type: `boolean`
- Default: `false`
Whether to get the last updated timestamp for each page using Git. The timestamp will be included in each page's page data, accessible via [`useData`](/reference/runtime-api#usedata).
Whether to get the last updated timestamp for each page using Git. The timestamp will be included in each page's page data, accessible via [`useData`](./runtime-api#usedata).
When using the default theme, enabling this option will display each page's last updated time. You can customize the text via [`themeConfig.lastUpdatedText`](./default-theme-config#lastupdatedtext) option.
@ -336,7 +336,15 @@ Configure Markdown parser options. VitePress uses [Markdown-it](https://github.c
export default {
markdown: {
theme: 'material-theme-palenight',
lineNumbers: true
lineNumbers: true,
// adjust how header anchors are generated,
// useful for integrating with tools that use different conventions
anchors: {
slugify(str) {
return encodeURIComponent(str)
}
}
}
}
```
@ -404,12 +412,28 @@ interface MarkdownOptions extends MarkdownIt.Options {
Pass raw [Vite Config](https://vitejs.dev/config/) to internal Vite dev server / bundler.
```js
export default {
vite: {
// Vite config options
}
}
```
### vue
- Type: `import('@vitejs/plugin-vue').Options`
Pass raw [`@vitejs/plugin-vue` options](https://github.com/vitejs/vite-plugin-vue/tree/main/packages/plugin-vue#options) to the internal plugin instance.
```js
export default {
vue: {
// @vitejs/plugin-vue options
}
}
```
## Build Hooks
VitePress build hooks allow you to add new functionality and behaviors to your website:
@ -475,6 +499,8 @@ export default {
```ts
interface TransformContext {
page: string // e.g. index.md (relative to srcDir)
assets: string[] // all non-js/css assets as fully resolved public URL
siteConfig: SiteConfig
siteData: SiteData
pageData: PageData

Loading…
Cancel
Save