Wednesday, 18 April, 2018 UTC


Summary

Documentation is food for the developer’s soul, and too many times we find it arduous to build out a documentation system for projects. In this post, we shall be building out a static documentation website which is also a single page application using the Vue powered static site builder, VuePress.
What are Static Sites?
Static sites are basically websites which are served as stored. There is no direct client-server interaction except from embedded third party applications. Static site generators abound the internet and each differs from the other, while some favor speed and load times over flexibility, some others tout extended functionalities. Static sites are preferred because of its increased speed and the absence of a server mitigates the likelihood of security flaws.
Recently released, VuePress features a static site generator as well as a default theme suited for building out documentation websites in no time. We shall be employing the default documentation theme to build out our system.
Why VuePress?
I say, why not VuePress! By default, VuePress Parses markdown files as structured in folders into HTML files to be served. VuePress ships out of the box with Vue, Vue Router for creating individual routes and webpack for bundling assets. During build, each markdown file created is parsed as a Vue template while assets are bundled by webpack. Parsing the markdown files into Vue templates creates an avenue with which we can also pass in native Vue scripts in the form of single file components.
VuePress is SEO friendly and by default provides a means to implement analytics tracking using google analytics on your pages. Also, VuePress ships with a minimal search system which indexes all headers on the website and displays them upon search.
While VuePress ships with a default responsive layout for documentation, it also supports custom layouts for styling. For this post, we shall build a minimal documentation system utilizing the default theme as well as implement the Vue in Markdown feature, by way of building a simple counter into a markdown file. Our final product will look like this:
Prerequisites
For this tutorial, it is assumed that you have substantial knowledge of HTML, CSS, and JavaScript. Knowledge of Vue is also of added advantage but not required.
Installation
For this project, you will require node and its package manager npm. you can check if you have it installed on your terminal by running:
node -v && npm -v
This displays the versions of node and npm installed respectively. If you don’t have it installed, you can download it from here.
Next up we create a new project. Create a new folder and change directory into it with:
mkdir scotch-vuepress && cd $_
Initialize a new node project in the scotch-vuepress directory with:
npm init -y
This quickly scaffolds a new project and creates a package.json file.
Next, we install VuePress locally with:
npm install -D vuepress
Once we have VuePress installed on our project, we are ready to go as it ships with the default documentation theme which we require. However, we would like to customize the documentation to suit our requirement, let’s get to creating the folders and the files even though with dummy text.
Creating Folders and Files
Care is taken when creating folders in VuePress as it evaluates the folders and markdown files according to their arrangement. Each markdown file in a folder compiles to a HTML document with the route being the parent folder. First, we create a docs folder which houses all the documentation content and configuration. Create it with:
mkdir docs && cd $_
In the docs directory, we shall proceed to create the .vuepress folder and the documentation folders housing the files - counter and guide.
Note, for each and any of these routes to work, we require a README.md file in each folder. This serves as a home route to that particular subsection.
The counter folder contains markdown files to be parsed as well as default README.md files for the home page. The guide folder contains similar contents to the counter folder.
The .vuepress folder houses the components directory, the dist folder which is created on build and the config.js file which is used to configure the overall system.

Creating Vue Components

For this project, we shall be building a minimal counter using Vue. Create two Vue components with the .vue suffix namely counter.vue and my-header.vue. These components will serve as a counter component and a simple header respectively. In my-header.vue, edit the vue script:
<template>
    <div>
        <h1>This Header is actually a Vue Template</h1>
    </div>
</template>
<script>

</script>
<style scoped>
</style>
Edit the counter.vue script to:
<template>
    <div class="counter">
        <h1>{{number}}</h1>
        <button @click = "increment">Increment</button>
        <button @click = "decrement">Decrement</button>
    </div>
</template>
<script>
    export default {
        data(){
            return{
                number: 0,
            }
        },
        methods:{
            increment(){
                if(this.number >= 0){
                    this.number++
                }
            },
            decrement(){
                if(this.number > 0){
                    this.number --
                }
            }
        }
    }
</script>
<style scoped>
.counter{
    display: inline-block;
    margin-left: 30%;
}
button{
    display: inline-block;
    padding: 20px;
    margin: 10px;
    font-weight: bold;
    border-radius: 5px;
    box-shadow: 0px 0px 5px 0px rgb(11, 11, 114);
}
h1{
    text-align: center;
}
</style>
This how simple building a counter gets. Currently, we have our Vue components, ready to be used.

Create Markdown files

We proceed to create markdown files in counter and guide directories. See the markdown files for counter and guide. Frontmatter is used to dynamically set the title of the individual pages. The <counter/> component is also placed in the markdown file.
These files will later be transformed into static pages. For our homepage, we would also require a README.md markdown file to serve as the homepage. Frontmatter in the markdown files is used to set some dynamic properties of the homepage. Create a README.md file in the docs directory and edit it to:
---
home: true
actionText: See Counter App
actionLink: /counter/counter-app
features:
- title: Embedded Vue Counter
    details: A Vue counter developed using Vue is embedded in this doc, now that's the power of VuePress!
- title: Fun Docs made with VuePress
    details: This entire doc was basically made with VuePress which parsed markdown files and corresponding assets using webpack.
footer: Developed using VuePress by William Imoh
---
We should be placing the my-header Vue component in the home route. Edit the README.md to include the component.
---
home: true
actionText: See Counter App
actionLink: /counter/counter-app
features:
- title: Embedded Vue Counter
    details: A Vue counter developed using Vue is embedded in this doc, now that's the power of VuePress!
- title: Fun Docs made with VuePress
    details: This entire doc was basically made with VuePress which parsed markdown files and corresponding assets using webpack.
footer: Developed using VuePress by William Imoh
---
<my-header></my-header>
So, far we have all the required Markdown files. Let’s proceed to configure the navigation and sidebar using .vuepress/config.js.

Configuring The Layout

The config.js file is used to customize the documentation system. In creating this custom system, we export an object containing required fields.
module.exports = {
    title: 'Scotch VuePress',
    description: "A demo documentation using VuePress",
    themeConfig:{
        nav: [
            { text: 'COUNTER', link: '/counter/' },
            { text: 'GUIDE', link: '/guide/' },
        ],
        sidebar: [
            {
                title: 'Counter',
                collapsable: false,
                children: [
                '/counter/counter-app'
                ]
            },
            {
                title: 'API Guide',
                collapsable: false,
                children: [
                    '/guide/guide',
                    '/guide/api'
                ]
            }
            ]
    }
}
First, we specify the title of the website and assign it a description which is great for SEO. This title and description input automatically provide an indexed search system on the website with a search bar.
Next in the script is the themeConfig object which receives parameters required to implement certain functionalities on the theme. To create a nav bar, we create a nav array which contains objects specifying the display text and route of each nav element. You can see more on configuring the default theme here.
We employed the use of grouped sidebars so we would be able to have a quick glance at the menu at any time in the documentation. The sidebar menu can be set to collapse by default using the collapsable property on the sidebar group. You can find more on the sidebar here.
Now we have everything set, to start a development server, run:
vuepress dev docs
The local dev server is hosted on port 8080. Good thing to note is that VuePress ships with a hot reload feature which implements any change made to the application during development.
Note that a restart of the development server is required if the Vue components are created while the local development server is live.
Notice the header created with the Vue template?
While we have a dev server running, the goal is to deploy the site. To clean things up a bit, edit the package.json file to include development commands as well as build commands. Edit the package.json file to:
{
    "name": "scotch-vuepress",
    "version": "1.0.0",
    "description": "",
    "main": "index.js",
    "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "docs:dev": "vuepress dev docs",
    "docs:build": "vuepress build docs"
    },
    "keywords": [],
    "author": "",
    "license": "MIT",
    "devDependencies": {
    "vuepress": "^0.5.0"
    }
}
To build the static files, we can now run:
npm run docs:build
This may take a while to build after which the static files built can be found in .vuepress/dist
Change Style
VuePress supports static files as well as webpack assets and care is taken to ensure that the URL assigned to an asset in markdown is correct before build. For our case, we just need to retouch the base color a little. We will proceed to override the default colors using stylus.
Create a new file called override.styl in docs/.vuepress. While making use of the variable names assigned to color as stated in the official documentation, we edit the override.styl script to change the accentColor with:
    $accentColor = #cfa809
    $textColor = #2c3e50
    $borderColor = #eaecef
    $codeBgColor = #282c34
Restart the development server with:
npm run docs:dev
Note that changes made to the stylus file reflects in the browser immediately.
We now have completed the documentation system with individual pages:
Deploy To Netlify
We shall proceed to deploy our static site using Netlify. Netlify provides an awesome continuous integration option by deploying from Github or any other supported hosted version control provider. Follow these steps to deploy your site to Netlify:
Step 1 Create an account on Github and Netlify. Push your code using Git to Github.
Step 2 Log in your Netlify account and select the ‘New site from Git’ option. Choose Github as the continuous development provider and select the repository containing the documentation.
Step 3 Specify the branch to deploy as master or choose whichever branch you would like to deploy. Set the build command to npm run docs:build and the publish directory to docs/.vuepress/dist. Click ‘Deploy Site’. Your website should be deployed in little time and a public URL is provided to access it.
Here is the deployed version of this tutorial on Netlify.
Conclusion
Static sites are considered for their speed, security, and maintainability. In this post we developed a static documentation website which is also a single paged app, using VuePress. VuePress offers the flexibility of writing Vue scripts inside Markdown files which introduces an amazing level of dynamism in static sites. Feel free to modify the documentation to include several folders and corresponding markdown files. Also check out the repository of this post and leave your comments and feedback. Happy coding!