How to create a custom VuePress theme with Vuetify
If you’ve heard of VuePress already you might know that it’s a powerfully minimal static site generator by Vue.js Creator Evan You. VuePress makes the creation of text-heavy documentation websites easy, a lot easier than Nuxt.js.
But, did you know that VuePress has a custom theme system built on top of Vue that lets you build your own fully featured themes with custom functionality?
In this article, we’ll go over how you can get started creating your own custom theme, some best practices to follow, and how to integrate a UI pattern library like Vuetify for fast layout creation.
For example, let’s take the VuePress documentation website itself. It’s using the default theme. The default theme comes out of the box with a lot of custom functionality like a built-in search, customizable nav and sidebars, and even an auto-generated GitHub link and page-edit links that are great if you’re hosting your website using GitHub Pages.
You’ll be able to build themes just as featured as the default theme. If you’ve used Vue.js for development before, you will see that the development experience is similar when you’re creating a custom theme. You can even use Vue DevTools to debug your custom theme.
So let’s get started.
Setting up a VuePress project
First, make sure that you have VuePress installed on your system.
npm install -g vuepress
Create a folder for your VuePress website with the following command: mkdir my-vuepress-project
.
Click here to learn more about integrating VuePress with an existing project.
Structuring your content
The beauty of VuePress is that it allows you to structure your content however you like. Every single markdown file in your project will be compiled into a static HTML file.
For example, your project might be structured something like the following:
So once your project has content, how do you start creating a custom theme to display that content?
Creating your custom VuePress theme
In the folder structure example above you might have noticed a folder named .vuepress
. This folder is where your configuration and all VuePress-specific files go. It’s also where your custom theme files will go.
To create a custom theme, create a theme
directory inside of the .vuepress
directory in your VuePress project, and then create a Layout.vue
file.
The Layout.vue component
The Layout.vue
component is the file that VuePress looks for when invoking your theme. It will be invoked once for every markdown file in your VuePress project.
For example, it will be invoked 4 times with our example structure, which has four markdown (.md) files.
Rendering your website’s content inside of your theme.
The simplest theme can be just a single Layout.vue
component with the following markup:
The compiled content of the current .md
file being rendered will be available as a special <Content/>
global component.
Another way to think about the Layout.vue
file is as the starting point for your theme because in reality, a fully fleshed out theme will require more than just a single file.
Structuring your VuePress theme
So what’s the recommended structure for a custom VuePress theme? There are no enforced rules, but many themes out in the wild are structured something like the following:
This structure allows you to organize your individual page layouts (like your Post and Home pages) in the layouts folder, and then have your individual components (that those layouts use) in the components folder.
Integrate a UI pattern library like Vuetify into your custom theme
Ultimately, VuePress custom themes are just Vue applications so you can do anything that you would normally do inside of your applications. For example, you can include a UI pattern library into your custom theme from npm.
From the terminal, cd
into your .vuepress
folder and then do an npm install vuetify — save
in order to get Vuetify into your custom theme.
Now you can take full advantage of any library inside of your theme and can fully customize your theme files.
Home.vue
Post.vue
Customizing your theme with your page’s data
Once you have a folder structure in place and have laid out your individual layout components, how do you get those individual components to render from Layout.vue
?
When it comes to your individual markdown files, VuePress gives you a lot of customization options. You can add YAML front-matter, a data serialization language commonly used for configuration, at the top of your markdown files and VuePress will automatically interpret it for you.
Each time Layout.vue
is called, the YAML that you have defined in your file, along with other VuePress-generated metadata, will be available inside of your Layout.vue
component as this.$page
.
For example, when processing your /guides/getting-started.md
file then your this.$page
variable might look something like the following:
{
"lastUpdated": 1524847549000,
"path": "/guides/getting-started.html",
"title": "Guides - Getting Started",
"frontmatter": {}
}
You can then use that data to customize the theme to your liking. For example, one thing you might do is render a different HTML / CSS layout for a different look depending on the path of the file.
Another variable that is injected is this.$site
that gives you information about your entire website.
{
"title": "VuePress",
"description": "Vue-powered Static Site Generator",
"base": "/",
"pages": [
{
"lastUpdated": 1524027677000,
"path": "/",
"title": "VuePress",
"frontmatter": {}
},
...
]
}
One example of what you can do with the this.$site.pages
array is looping through it and creating next and previous links.
The this.$site
and this.$page
properties are injected into every component inside of the .vuepress
folder.
Click here to learn more about all of the data that is injected into your components.
Extra Resources
Here are three custom VuePress themes up on GitHub that you can use as a reference to creating your own.
Or, you can just install them directly.
Click here to learn how to install these themes directly into your project.
Conclusion
Ultimately, creating a VuePress theme gives you just as much flexibility as creating a Vue.js app. You’re free to lay out your theme in the way that works best for you.
In this post, we went over some best practices, the data that you can use inside your theme components, and also how to integrate with a UI library like Vuetify for creating layouts.