Create compelling Documentation with Github Pages

by Thomas Reinecke and Kai Wedekind

In this article, you will learn how to use Github pages as a new home for your project documentation. This document describes the GIT Playbook project hosted on GitHub. A live demo of a Playbook runs here.

Git Playbook Demo screen

On one of our recent projects in IBM we’ve identified the strong need for Documentation consolidation. We’ve faced a number of typical issues:

  • fragmented, inconsistent, duplicate, to some degree ambivalent and incomplete documentation— we’ve had too much but at the same time not enough
  • Delivery happened on multiple document types (pdf, ppt, word, excel, txt) and via multiple channels (wikis, box, community files a.s.o) and no Search function was in place to pull all this together
  • We delivered on different quality (depending on the author) and with an inconsistent look & feel (Colors, Fonts, Font-sizes) — We did not deliver a unified Documentation UX

Sounds familiar, doesn’t it ? This article isn’t a story about the reasons for poor documentation or a discussion on why it matters. If you need more insights here, read more on the following article

This Article also isn’t around the actual art of technical writing, dive deeper here if you’re interested in this space:

This article is about the delivery platform for Technical Documentation.

Where do you wanna put your contents, what channels do you want it to be consumable with, how do you efficiently manage your contents even with thousands of pages and how can your users search through it ?

Here are a few thoughts of what we wanted to archive:

  • End-2-end One-Stop-Shop for all our Documentation
  • Easy creation of new pages and content structure
  • Govern and control look & feel centrally
  • Live Search
  • Responsive UX (for Sidebar and Mobile presentation)


The playbook page from above comes in a pretty slick but still very powerful look & feel. The main components we’ve put into the layout are:

Main Layout of Git-Playbook
  • Configurable Title — what ever you want it to be called, you can easily configure that
  • Live Search — the content is fully indexed and users can utilise this component to filter based on keywords and based on Topics (topic:myTopic to find all documents that carry this topic)
  • On or multiple Major Sections — when you actually need more than just one Playbook you can add them here OR you can reference one of the pages you will create and expose that on this prominent spot on the header
  • Table of Content Views — Documents that have no content but only Child docs show up as ToC pages that hold a number of Tiles. You can use these Tiles to dive deeper into the documentation
  • Tiles with Title, Icon & Description — sitting on a ToC page a Tile can be an actual document or a nested ToC page. A Tile comes with a Title, a very brief description and a free Icon from the Font Awesome 5 library
  • Table of Content for the Major Section — this is a component thats rendering a nice ToC for the full hierarchy of content that was configured for the Playbook

The actual Content Rendition page looks like this:

Markdown Content rendition page on the Playbook


Git-Playbook comes as a VueJS app, its purely Frontend— no need for any backend or API Services so its easily capable to be deployed to Github Pages, Gitlab Pages or some simple web container of your choice.

From a package.json perspective, Git-Playbook is based on the following main dependencies (besides others): fontawesome, axios, vue, vue-markdown, vue-tree-navigation.

code structure

Git-Playbook comes with a Banner and Header Vue component, a Router thats picking up the document hierarchy from configManager, a number of css styles, the DefaultPageRenderer view (which is the primary core component to render the UX of the Playbook), the main.js which defines the Font icons we want and the pageConfig.json which holds the document structure and hierarchy.


This JSON file holds the high-level configuration of Git-Playbook and the document structure.

# configures the name of the app on the top-left corner
"appName": "Git",
  # configures the header (showing up on the top-right)
"headerNavigation": [
"name": "Playbook",
"path": "/playbook"
  # which of the pages on the playbook is the default landing 
"landingPage": "/playbook",
  # configuration of the default page hierarchy
"pages": [
# the URL route we use to directly navigate to this page
"route": "/playbook",

# title of this page
"name": "Playbook",
      # description that shows up on the tile
"description": "This is the playbook",

# font awesome 5 icon from
"icon": "address-book",
      # array of topics this document should carry
"topics" : ["content", "main", "topic1"],
# nested children that belong to this document
"children": [
# relative route to this nested doc, absolute route is
# /playbook/whatsNew

"route": "/whatsNew",
"name": "Whats new ?",
"description": "recent announcements, news, ...",
"icon": "bullhorn",
"topics" : ["topic1"],
# reference to the actual content (markdown on static)
"markdown" : "/static/markdown/whatsnew/"
"route": "/links",
"name": "Helpful Links",
"description": "how to go from here ?",
"icon": "link",
"topics" : ["links", "topic2"],
"markdown" : "/static/markdown/"
"route": "/faq",
"name": "FAQs",
"description": "frequently asked questions are ...",
"icon": "question-circle",
"topics" : ["links", "topic2"],
"markdown" : "/static/markdown/"
"route": "/roadmap",
"name": "Our Roadmap",
"description": "aligning our development plans ...",
"icon": "map-marked-alt",
"markdown" : "/static/markdown/"
"route": "/process",
"name": "Process Documentation",
"description": "anything about support process ...",
"icon": "project-diagram",
          # grand-children from the root node perspective
"children": [
"route": "/introduction",
"name": "Process Introduction",
"description": "how to read the process doc",
"icon": "project-diagram",
"markdown" : "/static/markdown/process/"
"route": "/newPagesHowto",
"name": "New Pages HowTo",
"description": "how to create new Pages on ...",
"icon": "file-alt",
"markdown" : "/static/markdown/process/"

To add a new Page into the document hierarchy, simply duplicate one of the objects from pages and fill its appropriate values. If you want a ToC page, you need to use nested “children”. If you want a content page, you need to create the actual Content file (in Markdown) stored on the static folder and then reference its path on the “markdown” field. This procedure allows you to create whatever complexity you need for your product documentation on whatever levels of depth you want.

If you clone the “Git-Playbook” repository, this is the only file you need to touch.


This service file exposes a number of utilities for the DefaultPageRenderer and the Router:

  • generateRoutingConfig — recursively iterates through the document hierarchy (based on processElement function) given by pageConfig.json. Is creating the compatible config structure for Vue Router and for the Vue Tree Navigation component.
* generateRoutingConfig - generates the routing for VueRouter out
* of the pageConfig.pages
function generateRoutingConfig (baseConfig) {
let pages = JSON.parse(JSON.stringify(baseConfig.pages))
for (let i in pages) {
let element = pages[i]
processElement(element, null)
  // configure the default landing page
path: '/',
redirect: baseConfig.landingPage
return pages


This vue component is the actual heart of Git-Playbook since it renders the main view area depending on the nature of the document is is expected to display. Table of Content pages will be rendered in the tiles-based experience mentioned above, whilst for pages that carry actual contents their markdown contents is rendered. The full source of the component can be inspected at the GH repo, here’s just the HTML template portion.

<div class="container" @scroll="handleScroll">
    <!-- display the banner on the page -->
<section class="banner"
:class="{ active: isActive }"
v-if="pageConfig && !pageConfig.tiles"
      <h2 class="banner__title heading-1">{{ }}</h2>
<h4 class="banner__title heading-4">{{pageConfig.description}}
<p class="banner__text banner__text--timestamp">
{{ lastModified }}
    <!-- render the markdown when content is available -->
<vue-markdown class="content" :source="markdown"></vue-markdown>
    <-- display the tiles, when children are available -->
<ul class="cards" v-if="pageConfig.tiles">
<li class="card" @click="switchPage(tile)"
v-for="tile in pageConfig.tiles"
v-bind:style="{ backgroundColor: tile.bgColor }">
<font-awesome-icon class="card__icon"
<h4 class="card__title">{{}}</h4>
<p class="card__text">{{tile.description}}</p>

Deploy to GH Pages & Search Index generation

Building GIT Playbook including its search index is very straight forward:

npm run build 

To deploy your Playbook to GH pages, run

npm run gh-pages

In your GH repository > Settings > scroll down to “Github Pages”, make sure it points to your “gh-pages” branch. You’ll find the link to your GH page deployment on that screen aswell:

GH pages configuration for the playbook

Checkout the Demo of the playbook here. You’ll notice that also the Search index now works (which usually isn’t available on your development environment unless you serve it locally):

Usage of Topics to group documents together

With version 1.1.0 we’ve just introduced a new feature called “Topics” that allows to group documents together. On pageConfig.json, on any documents scope, add a new JsonArray “topics” containing a list of terms that are your topic labels. The documents now render the topic as buttons into the document pages:

Clicking this link will open the search screen with the search term “topic:news” which will list all documents that carry this topic label.

Alternatives to Git Playbook

There is a number of noticable alternatives to Git Playbook that I also recommend to check out to dive deeper:

Not my take here to evaluate their differences, overall Git Playbook is much more lightweight and/or feature rich than these mentioned alternatives. Decide for yourself.

Questions ? Feedback. Feel free to contact us either here on the comments or on GitHub. Thank you