Building Static Websites

David K. Zhang
Last Modified 2024-09-03

This website is static, which means that it consists of a fixed set of HTML, CSS, and JavaScript files. Writing those files by hand can be tedious, so in these notes, I’ll describe the tools I’ve created to automate the process of building dkzhang.com.

There are lots of popular and well-tested tools for creating static websites, like Jekyll and Hugo. I chose to design my own static site generator for a few reasons:

All of the tools I’ve developed for building dkzhang.com are open-source and freely available on GitHub in the dzhang314/my-markdown-docs repository. If you’d like to create a similar website, please feel free to use my files as a starting point — but be aware that they are highly tailored to my specific preferences, and you will likely want to adapt them to suit your own taste.

Overview

Every page on my website is generated from a Markdown file in dzhang314/my-markdown-docs. These Markdown files, together with a few HTML/CSS templates and a JS build script, are the only manually-written files I use to create dkzhang.com.

Each page has the same basic structure outlined in dkzhang-template.html. This template has four fields that build.mjs fills in to generate the final HTML file for each page.

Components

Most of the content on this website is built from basic HTML elements, like <h1> titles, <h2> headings, <p> paragraphs, and <ul> lists. In addition, I use two special components from Bootstrap 5.3. First, a fixed-top Bootstrap Navbar provides a navigation interface that sticks to the top of the page as you scroll. I apply navbar-expand-md to collapse the navbar into a hamburger menu on smaller screens and d-print-none to hide the navbar when printing. Second, I use Bootstrap cards to call attention to important information and set mathematical definitions and proofs apart from surrounding descriptive text.

The structure of the navbar is defined in dkzhang-navbar.html, which I manually edit every time I add a new page. I might automate the process of generating the navbar in the future, but I don’t have enough pages to necessitate that yet.

Style

The style of this website is based on the Bootswatch Litera theme with a few manual tweaks in dkzhang-style.css to adjust navbar and card padding. I apply a max-width constraint to the main container-lg to improve legibility and ensure consistent printing. A width of 19cm fits A4 paper with 1cm margins and US Letter paper with 0.5" margins.

I display text using the STIX fonts, which are optimized for legibility on both screen and print media and are conveniently hosted by Google Fonts. To match the STIX glyphs, I display code using Fira Code at font-size: 1.0rem; and slightly enlarge the KaTeX math font with .katex { font-size: 1.05em; }.

Rendering

Every page on my website is written in Markdown, a lightweight markup language which is easier to write by hand than HTML. Using markdown-it, an extensible Markdown-to-HTML renderer, I developed my own dialect of Markdown with two extensions:

I use katex.renderToString to render math to static HTML elements that display correctly even when JavaScript is disabled. I also maintain a collection of TeX macros with helpful abbreviations that I’ve developed for real-time note-taking during lectures and seminars.

Writing

My markdown-it rendering pipeline is fast enough to run on every keystroke as I type. I use VSCode with the Live Preview and Run on Save extensions to automatically run build.mjs and view the final rendered webpage in real time while I write. This is especially helpful for typesetting complex equations and fiddling with line breaks.

You can try out my writing setup at dkzhang.com/ZhangEdit, a live in-browser Markdown editor that uses the same markdown-it extensions and CSS styles as my website.

Hosting

This website is hosted on GitHub Pages, which provides free hosting for static websites. When you visit dkzhang.com, GitHub’s servers send you the bundle of generated HTML files that I’ve uploaded to this GitHub repository (which is different from my-markdown-docs).

Since my GitHub username is dzhang314, this website would normally be hosted at the URL dzhang314.github.io. To make it appear at dkzhang.com, I’ve configured a custom domain that I purchased through Squarespace Domains (formerly Google Domains) for $12/year.