Documentation is a crucial aspect of software development. But developers often neglect it because it can be a hassle to maintain. This is why it's important to use tools that help simplify this process.

In this tutorial, you'll learn how to build a complete docs site quickly by utilizing a modern tool called VitePress.

What is VitePress?

VitePress is a simple and performant static site generator built on top of Vite that lets you create docs in a matter of minutes. It is powered by Vuejs and Vite with built-in customizable components.

VitePress powers some popular documentation sites like Vuejs, Vitest, faker.js, and Vite itself.

Prerequisites

To follow along with this tutorial, you need to have a basic understanding of the following:

  • Markdown syntax
  • Basic understanding of NPM and Vite

Here's a screenshot of what you'll build by the end of this tutorial:

final-works-2

Want to play around with it? Check out the live demo. Also, the source code for this can be found on GitHub.

Step 1: Create a New Project

If you already have a folder created, you can skip this step and go on to the next one. If not, use the following command to create a project folder and move into the folder.

mkdir project-name
cd project-name

Next you need to initialize the project with your preferred package manager. I'll be using NPM for the rest of this guide.

npm init
// or use this command if you want to skip all the questions
npm init -y

If you used the first command, you'll be prompted with certain questions, so just complete them as appropriate.

After a successful operation, you should have a package.json file in your root directory. This is where the VitePress dev dependency will be installed.

Step 2: Install VitePress

The next step is to add VitePress and Vue as dev dependencies to your project, like this:

npm install --dev vitepress vue

You've successfully installed VitePress and Vue and added them as dev dependencies. Now you can start creating creating your respective doc files.

But before you do that, I believe it's essential to explain how VitePress works.

How Does VitePress Vork?

VitePress makes use of Markdown .md files for its markup which is automatically converted into static HTML. In other for this to work, a special folder called docs gets created in the root directory.

This folder behaves similarly to the pages folder in NextJS, where any .js file created in the directory is automatically treated as a web page. In this case a file called index.md will be the treated as index.html and serve as the root of your docs template.

Now that you understand how that works, you can create your respective doc files.

Step 3: Create the Respective Doc Files

You can create the docs folder and the index.md file manually, or you can do it with the terminal like a hacker.

mkdir docs && echo '# Hello VitePress' > docs/index.md

This command simply creates a folder called docs and adds an index.md file containing a h1 element that says "Hello World".

create-respective-files

With this, you can boot up your dev environment to see what has been created so far.

Step 4: Boot Up Your Dev Environment

In order to run your docs locally, you need to add the following scripts inside the package.json file. Simply copy the code below and replace the "script" object with it:

// package.json
"scripts": {
    "docs:dev": "vitepress dev docs",
    "docs:build": "vitepress build docs",
    "docs:serve": "vitepress serve docs"
  },

Finally, the documentation site can be served on a local server by running the command below:

npm run docs:dev

This will start a hot-reloading development server at http://localhost:5173, and you can visit it to see your docs site.

Here's the output:

boot-dev-server

All you had to do was add the markup and VitePress handled the appearance from its template engine. In the next session, you'll learn how you can customize the docs to fit your needs.

How to Customize Your Docs with VitePress

First create a .vitepress folder inside the docs directory you created earlier on. This is where all VitePress-specific files will be placed.

Inside this new directory, you need a config.js file. Again, you can use the terminal command like so:

mkdir .vitepress && touch .vitepress/config.js

To test this config file, you can start by changing the meta title and description of your docs site. Copy this markup and paste into the config.js file:

// .vitepress/config.js
export default {
  title: 'Adocs',
  description: 'An awesome docs template built by me'
}

If you check the dev tools, you should see the changes in the meta title and description.

title-and-description

In order to change the logo title and add an image, copy the markup below and paste it into a new object called themeConfig inside the same config.js file. This will overwrite the current title and add a logo to your docs site.

// config.js
export default {
  themeConfig: {
    logo: "/logo.svg",
    siteTitle: "Adocs",
  },
};

For the image source, you can pass in an image URL or specify the path to a local image. To do it locally, make sure you place the image within the public directory.

Here's the output:

logo-and-title

Note that files in the public directory are served at the root path. So instead of ../public/logo.svg, just use /logo.svg.

How to Customize the Navbar

Customizing the Navbar is a pretty straightforward process as well. Inside your themeConfig file, paste the markup below. Here we have an object that contains two properties: the anchor text text, and the path link defines the URL path.

// .vitepress/config.js
{  
  // ...
   nav: [
    { text: "About", link: "/about" },
    { text: "Contact", link: "/contact" },
    { text: "Guide", link: "/guide" },
    { text: "Configs", link: "/configs" },
    { text: "Changelog", link: "https://github.com/..." },
  ],
  // ...     
}

Essentially navigating to localhost:5173/about should take you to an about page (though we haven't created that yet).

Here's the output:

navigaiton-menu

Navigation links can also be dropdown menus, too. To add one, simply replace any of the links property with the items object which contains an array of links.

// .vitepress/config.js
{
  text: "Changelog",
  items: [
   { text: "v0.0.1", link: "/item-1" },
   { text: "v0.0.2", link: "/item-2" },
   { text: "v0.0.3", link: "/item-3" },
  ],
},

Now the changelog will become a dropdown menu with the respective links you pass inside.

Here's the output:

dropdown-menu

How to Add Social Icons

Navigation menus usually have social icons that visitors can use to visit your social platforms. To add them, define a new object called socialLinks inside themeConfig and simply pass in the social icon and the link you want it to navigate to.

// .vitepress/config.js
socialLinks: [
  { icon: "github", link: "https://github.com/Evavic44/adocs" },
  { icon: "twitter", link: "https://twitter.com/victorekea" },
  { icon: "discord", link: "..." },
]

By default, only 8 icons (Discord, Facebook, GitHub, Instagram, LinkedIn, Slack, Twitter, and YouTube) are provided. If you want to add a custom icon, use the SVG property to define an svg image. You can get free icons from icones.js.org.

For example, here's a snippet of the apple icon.

{
  icon: {
    svg: '<svg role="img" width="26.01" height="32" viewBox="0 0 256 315"><path d="M213.803 167.03c.442 47.58 41.74 63.413 42.197 63.615c-.35 1.116-6.599 22.563-21.757 44.716c-13.104 19.153-26.705 38.235-48.13 38.63c-21.05.388-27.82-12.483-51.888-12.483c-24.061 0-31.582 12.088-51.51 12.871c-20.68.783-36.428-20.71-49.64-39.793c-27-39.033-47.633-110.3-19.928-158.406c13.763-23.89 38.36-39.017 65.056-39.405c20.307-.387 39.475 13.662 51.889 13.662c12.406 0 35.699-16.895 60.186-14.414c10.25.427 39.026 4.14 57.503 31.186c-1.49.923-34.335 20.044-33.978 59.822M174.24 50.199c10.98-13.29 18.369-31.79 16.353-50.199c-15.826.636-34.962 10.546-46.314 23.828c-10.173 11.763-19.082 30.589-16.678 48.633c17.64 1.365 35.66-8.964 46.64-22.262"/></svg>',
    },
  link: "https://www.apple.com/",
},

For custom SVG icons, make sure you add the role="img" property to the svg tag, as this allows the string convert it properly.

Here's the output:

social-icons

How to Add a Sidebar

VitePress also comes with built-in components like sidebar menus. To add a sidebar, create an object called sidebar and inside it, add nested objects that take in three values: the nested title, collapsible functionality (default is set to true), and the nested links.

// .vitepress/config.js
sidebar: [
    {
      text: "Section A",
      collapsible: true,
      items: [
        { text: "Introduction", link: "/introduction" },
        { text: "Getting Started", link: "/getting-started" },
      ],
    },
    {
      text: "Section B",
      collapsible: false,
      items: [
        { text: "Introduction", link: "/introduction" },
        { text: "Getting Started", link: "/getting-started" },
      ],
    },
    {
      text: "Section C",
      collapsible: true,
      items: [
        { text: "Introduction", link: "/introduction" },
        { text: "Getting Started", link: "/getting-started" },
      ],
    },
  ],

By adding collapsible: "true" to the sidebar object, it shows a toggle button to hide/show each section. You can create as many sections as you want.

Here's the output:

sidebar-2

You can see section B is not collapsible, and we have that nice next page button on the bottom of the page.

How to Set Up Page Routing

As explained earlier, VitePress automatically converts every .md file inside the root of the docs directory to static HTML that can be accessed in the address bar. For instance the index.md is converted to index.html, and about.md, about.html and so on.

Since you've created your nav links and pointed them to their respective URLs, you can access these pages easily by creating them.

docs/
├── .vitepress/
│   └── config.js
├── public/
│   └── logo.svg
├── about.md
├── contact.md
├── guide.md
├── configs.md
└── get-started.md

Create these files inside your docs folder and add a simple markup inside them just to see how this works. This page is basic markdown so all your markdown syntax like links, code blocks, headings, and so on works here.

Just for testing purposes, copy this markdown content and paste it inside any of the .md files you just created:

# About

Welcome to the about page.

This markdown supports html elements like the `p` tag coupled with inline styles

<p style="color: #ff7340; border: 1px solid rgba(255, 135, 23, 0.25); border-radius:5px; padding: 1rem;">Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s.</p>

Even satire code snippets with syntax highlighting are also supported. 😅

```js
const lang = prompt("What is your favorite programming language?");

(lang === "JavaScript") | (lang === "javascript") | (lang === "js")
  ? alert("JavaScript to the world! 🚀🟡")
  : alert(`We don't permit such languages here 💩`);
```

Of course, images are not left out.

<img src="/logo.svg" alt="adocs logo">

Here's the output:

page-routing-2

Great! You've set-up the docs, added a navigation menu with a dropdown feature, added a sidebar, and customized the links to navigate to different pages. Next up, let's work on the home page.

How to Customize the Homepage

Just like every other component, VitePress provides us with markup for building the homepage. I've broken it down into three parts: Hero, features, and footer section.

The Hero Section

First, we'll start with the hero section. Replace the Hello World text in the index.md page with the following markup:

# docs/index.md
---
layout: home

hero:
  name: Adocs
  text: Static docs template built with VitePress.
  image:
    src: /logo-big.svg
    alt: Adocs logo
  tagline: A free to use template for creating docs for your projects
  actions:
    - theme: brand
      text: Get Started
      link: /get-started
    - theme: alt
      text: View on GitHub
      link: https://github.com/evavic44/adocs-template
---

The Features Section

Additionally, you can add a features section after the hero section. Simply paste the code below under the hero objects:

# /docs/index.md
---
link: https://github.com/evavic44/adocs-template

features:
  - icon: ⚡️
    title: Adocs, The DX that can't be beat
    details: Lorem ipsum...
  - icon: 🎉
    title: Power of Vue meets Markdown
    details: Lorem ipsum...
  - icon: 🔥
    title: Simple and minimal, always
    details: Lorem ipsum...
  - icon: 🎀
    title: Stylish and cool
    details: Lorem ipsum...
---

Here's the output:

hero-redesign

You can add a footer message on the bottom of the page, but this will only show up in the home page.

According to the VitePress docs:

Note that the footer will not be displayed when the SideBar is visible.

To add the footer component, go to the config.js file and paste the markup inside the themeConfig object:

// .vitepress/config.js
 footer: {
   message: "Released under the MIT License.",
   copyright: "Copyright © 2022-present Adocs",
 },

Here's the output:

footer-2

Aside from the markup, you can also customize the components using custom CSS to change things like fonts family, colors, layout, ETC.

How to Add Custom CSS

The default theme CSS is customized by overriding root level CSS variables. If you want, you can check out the full list of CSS variables that are customizable.

To do get started, create a .vitepress/theme directory, and inside this theme folder, add an index.js and custom.css file. If you've been following along, you can use the terminal command below to do this quickly:

mkdir docs/.vitepress/theme && touch docs/.vitepress/theme/index.js && touch docs/.vitepress/theme/custom.css

If you run into any issues with the terminal command, just create the files manually and move on to the next step.

Here's an overview of the folder structure:

docs/
├── .vitepress/
│   ├── config.js
│   └── theme/
│       ├── index.js
│       └── custom.css
├── public/
│   └── logo.svg
├── about.md
├── contact.md
├── guide.md
├── configs.md
└── get-started.md

After creating these files, inside the .vitepress/theme/index.js file, paste the import commands:

// .vitepress/theme/index.js
import DefaultTheme from "vitepress/theme";
import "./custom.css";

export default DefaultTheme;

Color Theme

The colors are controlled by the CSS variables. You can simply replace them with any colors you want.

Note that this color has a provision for both light and dark mode. So make sure you change them accordingly.

Here's an example of my custom colors:

/* .vitepress/theme/custom.css */

:root {
  --vp-c-brand: rgb(255, 115, 64);
  --vp-c-brand-light: rgb(255, 87, 25);
  --vp-c-brand-lighter: rgb(255, 115, 64);
  --vp-c-brand-dark: #FF622D;
  --vp-c-brand-darker: rgb(226, 60, 0);

  --vp-c-sponsor: #fd1d7c;
}

If you don't see the effects immediately, try stopping the server and starting it again.

Aside from the color themes, you can also override other things like font family, typography, layout, breakpoints, and so on.

How to Use Custom Fonts

You can import Google fonts inside the CSS file to override the default font family.

@import url(https://fonts.googleapis.com/css?family=Space+Mono:regular,italic,700,700italic);
@import url(https://fonts.googleapis.com/css?family=Space+Grotesk:regular,italic,700,700italic);

:root {
  --vp-c-brand: #ff7340;
  --vp-c-brand-light: #ff5719;
  --vp-c-brand-lighter: #ff7340;
  --vp-c-brand-lighter: rgba(255, 135, 23, 0.25);
  --vp-c-brand-dark: #ff622d;
  --vp-c-brand-darker: #e23c00;

  --vp-c-sponsor: #fd1d7c;

  /* Typography */
  --vp-font-family-base: "Space Grotesk", "Inter var experimental", "Inter var",
    -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu,
    Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;

  /* Code Snippet font */
  --vp-font-family-mono: "Space Mono", Menlo, Monaco, Consolas, "Courier New",
    monospace;
}

With the --vp-font-family-base variable you can change the main font and --vp-font-family-mono, the font for code snippets.

Here's the output:

final-works

You've successfully customized the theme and changed the font family using CSS. Though there's more you can do in regards to styling, but at this point, I hope it's clear how you can customize your docs with CSS.

Let's discuss hosting in the next section.

How to Host Your Doc Site

You can publish or host your docs site when you're done to different platforms like Netlify, Vercel, AWS Amplify, and so on.

First, run the build command:

npm run docs:build

This should create a new dist folder that contains all the static files of your docs.

In deciding on what hosting service to use, you can pick any of the options I mentioned earlier but we'll be using Vercel in this guide. Also, feel free to look at other alternatives of your choice.

If you don't have a Vercel account, follow this guide to create one and configure your Git provider before you move on to the next step.

Assuming you've successfully set-up your account and uploaded your docs site to Vercel, navigate to the project > settings > build and deploy settings, and paste the following commands to their respective fields:

  • Build command: npm run docs:build
  • Output directory:  docs/.vitepress/dist
deploy-settings-vercel

After editing the settings, save them and deploy your site!

Conclusion

In this tutorial, you've set-up a full-fledged documentation site and customized it using CSS and VitePress built-in components.

Just keep in mind that this tutorial only covers a fragment of what is possible with VitePress. To learn more, check out the VitePress docs.

Additional Reading

Here are a few things not covered in this article that I think is also worth looking into:

Resources

If you are an open source fan like myself or you enjoy hearing about such cool projects, do follow me on my socials so you don't miss my next post. Cheers. 🍷

GitHub | Twitter | Blog | Portfolio