Set up a blog using GitHub Pages, write with Markdown (and Vue) with VitePress
Cheap, fast, good. Pick 2 all 3!
I have looked at a lot of templating engines, web design services, web hosting solutions, http(s) serving libraries, static site generators, content delivery networks, CSS stylesheet generators, style reset and bootstrapping templates, javascript libraries, javascript frameworks, javascript servers (😬).
I think I found the best solution
(for me, for use as a developer blog).
Background
In my professional work I spend most of my time on the backend, implementing service APIs and designing DB schemata, but I keep an eye on the frontend, and web technologies, and related services... because that's where the rubber meets the road. And it is evolving so often that you have to be constantly watching, or the learning curve to catch up becomes rather steep.
What I found, though, is when it comes to a blogging platform they are usually either too managed (wordpress and the like) or too much overhead (hosting a whole web service just to keep the lights on). Sure, there are conveniences in the managed services: they get the economy of scale from shared hosting and they offer a web-form interface for updating content. If what you are publishing is mostly text and images, and layout or interactivity are consistent and don't change often, these are decent options, but they can also be constraining on layout and certain elements of design, even with the large variety of template choices.
On the other side of things is hosting a dedicated blog server, probably using a PaaS like AWS, GCP or Linode. This introduces significant new costs, even at the cheap/free tier, because it's not just the one or two servers for hosting the (mostly static) content. There needs to be some kind of load balancing and DDoS protection in front of it. For bandwidth it will probably offload a lot of resources to a CDN (content delivery network). Telemetry, deployment, etc. Maybe not v1, sure, but soon enough to justify being aware of the trade-offs.
I also wanted something that could host interactive demos of work in progress, and that means being able to embed the web UI into the blog somehow. Of course it is possible to do this across libraries or technologies (if necessary it can always be embedded in an <iframe>
). But if I can reuse the same framework and occasionally even hoist the entire partial representation into the blog assets, well that reduces the friction between building and sharing a lot. I had already chosen Vue as the framework to support the (human) interface for my General Game Playing project, so finding a Vue-based site generator is great.
The Right Stuff?
This isn't necessarily the best solution for you, nor is it the best solution for something that requires a more dynamic server-side setup. The convincing parts for me:
✔️ Pros | ❗ Cons |
---|---|
Markdown integration | posts are actually a mix of YAML + markdown + Vue components |
Vue3 integration | folder structure and implementation is unorthodox |
statically-generated template output and excerpts | needs familiarity with SSR and Vue internals to make the most of it |
Free hosting | but limited to public repos with Pages content that can fit in a 1GB tarball |
Very, very extensible |
For me, this is the right balance. It gives me ample control over the content and doesn't cost me much (in either money or maintenance burden). I'm still developing an application server for my company's major product but this lets me begin writing about it without having to build out much of the infrastructure first.
If you want to give the setup a test drive before trying these instructions, you can try it direclty in your browser on StackBlitz!
Specification
In this article I will give a step-by-step guide to deploying the same setup as what I have done for this blog.
- VitePress
- ➕ mermaid extension for markdown (auto-layout for diagrams)
- ➕ index page with summary of recent posts
- ➕ prev/next posts inferred from file paths
- ➕ support draft editions (saved to source control but not yet published)
What VitePress gives you out of the box is actually very useful, but I am adding these few more features that really complete it for me.
Requirements
Before starting, you should have a local environment where you can set up the repo and install the SSG tooling that VitePress needs to generate static (HTML) content from the markdown (.md) and Vue (.vue) file source.
These are noted on the VitePress site as well, and may have been updated since I published this post, so check there for exact version requirements.
- Node.js, version 18 or higher (github also requires v18+)
- Terminal for accessing the VitePress command-line interface
- Text Editor with markdown support
- VSCode is my choice. Obsidian and StackEdit are also good options, and many others
- a GitHub account for publishing to GitHub Pages, and a repo.
Also, if you have a custom domain name, you can point it at the GitHub Pages site, so it's not even obvious that you're hosting this on a free source control platform. Other than the annual cost of the domain name, the rest of this solution is completely free, and the quota requirements very reasonable for this kind of blog.
Installation
First we need to install VitePress and its dependencies. Make sure you have installed node and npm first (Download Node for your OS from the nodejs site and follow the instructions there).
Installing VitePress
From a terminal window, run the following command to install VitePress:
npm add -D vitepress
Installing the mermaid extension (optional)
This can also be installed via NPM. If you don't care about embedding UML-style and workflow-style graphs in your posts then you may want to skip this step.
npm i -D vitepress-plugin-mermaid mermaid
This installs both the mermaid library and the extension to vitepress that enables embedding them directly in the markdown for a post. You'll see them and their dependencies reflected in package.json.
Hosting
Create (or reuse) a github repo
...TODO
and clone that repo to your local development environment
git clone $REPOSITORY_PATH
where $REPOSITORY_PATH is the link representing your git repo, it can be found on github under the blue <> Code
button at your repo's main page and looks like https://github.com/USER/REPO.git
. If you prefer to use SSH or the GH CLI, those are also valid options.
Run the VitePress setup wizard
Next change to that directory (cd myblog
) and run the vitepress setup wizard:
npx vitepress init
This will ask