Skip to content

Installing VitePress

bash
npm add -D vitepress

Setup Wizard

bash
npx vitepress init

The config file (.vitepress/config.js) allows you to customize various aspects of your VitePress site.

You can also configure the behavior of the theme via the themeConfig option. Consult the Config Reference for full details on all config options.


Markdown files outside the .vitepress directory are considered source files.

bash
npm run docs:dev

# direct methos
npx vitepress dev docs

CLI Reference.

bash
npm run docs:build

npm run docs:preview

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.


Routing

Project root is .vitepress special directory reserved for config files, dev server cache, build output and theme customization code.

If your VitePress project is located in ./docs, you should run vitepress dev docs

Source Directory is where Markdown source files live, it is the same as the project root. However, you can configure it via the srcDir config option.

Linking Between Pages

You can use both absolute and relative paths when linking between pages. Note that although both .md and .html extensions will work, the best practice is to omit file extensions so that VitePress can generate the final URLs based on your config.

bash
<!-- Do -->
[Getting Started](./getting-started)
[Getting Started](../guide/getting-started)

<!-- Don't -->
[Getting Started](./getting-started.md)
[Getting Started](./getting-started.html)

Asset Handling.


If you want to link to a page in your site that is not generated by VitePress, you'll either need to use the full URL (opens in a new tab) or explicitly specify the target:

There was an issue while loading static pages(extra HTML) to load since no proper root was present as it was not generated by Vite, so Absolute link works instead of relative link.

[Link to pure.html](/pure.html){target="_self"}

Route Rewrites

.
└─ 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/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 option like this:

.vitepress/config.js

export default {
  rewrites: {
    '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'
  }
}

The rewrites option also supports dynamic route parameters. In the above example, it would be verbose to list all the paths if you have many packages. Given that they all have the same file structure, you can simplify the config like this:

export default {
  rewrites: {
    'packages/:pkg/src/:slug*': ':pkg/:slug*'
  }
}

The rewrite paths are compiled using the path-to-regexp package - consult its documentation for more advanced syntax.


Accessing Params in Page

You can use the params to pass additional data to each page. The Markdown route file can access the current page params in Vue expressions via the $params global property:

- package name: {{ $params.pkg }}
- version: {{ $params.version }}

You can also access the current page's params via the useData runtime API. This is available in both Markdown files and Vue components:

<script setup>
import { useData } from 'vitepress'

// params is a Vue ref
const { params } = useData()

console.log(params.value)
</script>

Rendering Raw Content

Params passed to the page will be serialized in the client JavaScript payload, so you should avoid passing heavy data in params, for example raw Markdown or HTML content fetched from a remote CMS.

Instead, you can pass such content to each page using the content property on each path object:

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 // raw Markdown or HTML
      }
    })
  }
}

Then, use the following special syntax to render the content as part of the Markdown file itself:

<!-- @content -->

The following guides are based on some shared assumptions:

  • 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:

{
  "scripts": {
    "docs:build": "vitepress build docs",
    "docs:preview": "vitepress preview docs"
  }
}

If you're using Github (or GitLab) Pages and deploying to user.github.io/repo/, then set your base to /repo/.

For GitHub pages Create a file named deploy.yml inside .github/workflows directory of your project.

yaml
# Sample workflow for building and deploying a VitePress site to GitHub Pages
#
name: Deploy VitePress site to Pages

on:
  # Runs on pushes targeting the `main` branch. Change this to `master` if you're
  # using the `master` branch as the default branch.
  push:
    branches: [main]

  # Allows you to run this workflow manually from the Actions tab
  workflow_dispatch:

# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
permissions:
  contents: read
  pages: write
  id-token: write

# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
concurrency:
  group: pages
  cancel-in-progress: false

jobs:
  # Build job
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0 # Not needed if lastUpdated is not enabled
      # - uses: pnpm/action-setup@v3 # Uncomment this block if you're using pnpm
      #   with:
      #     version: 9 # Not needed if you've set "packageManager" in package.json
      # - uses: oven-sh/setup-bun@v1 # Uncomment this if you're using Bun
      - name: Setup Node
        uses: actions/setup-node@v4
        with:
          node-version: 22
          cache: npm # or pnpm / yarn
      - name: Setup Pages
        uses: actions/configure-pages@v4
      - name: Install dependencies
        run: npm ci # or pnpm install / yarn install / bun install
      - name: Build with VitePress
        run: npm run docs:build # or pnpm docs:build / yarn docs:build / bun run docs:build
      - name: Upload artifact
        uses: actions/upload-pages-artifact@v3
        with:
          path: docs/.vitepress/dist

  # Deployment job
  deploy:
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    needs: build
    runs-on: ubuntu-latest
    name: Deploy
    steps:
      - name: Deploy to GitHub Pages
        id: deployment
        uses: actions/deploy-pages@v4

In your repository's settings under "Pages" menu item, select "GitHub Actions" in "Build and deployment > Source".


Made with ❤️ for students, by a fellow learner.