Stacks for Simple Static Sites

Posted on Sat 17 February 2024 in general

Wouldn't it be great if you could type out an article on your computer, push a couple of buttons, and have it appear on the web? No clunky page builders, no admin logins, and no mandatory updates.

With the right setup for your website, this is possible.

I wrote about the benefits of simple sites before. But I didn't say how to actually create one.

This article looks at the general shape of a static site and some of the options available.

A stack for a static site needs to include:

  • A way to build the site - how does your content go from plain text to a web page?
  • A web host and CI/CD - whose servers are your content hosted on? How does your content get from your computer to the web?
  • (Optional) Interactions and addons - how do you handle interactive parts of the site like form submissions? How do you embed analytics?

Let's examine each of these.

Building the Site

To make a decent static site we need a way to build it from source files. This is necessary because:

  • HTML documents have poor support for repeating components. That means that your header, sidebar, and other elements that should be the same between pages will need to be copied beween pages manually if you use plain HTML. While the <template> tag and shadow DOM can work around this, their interfaces aren't exactly simple.
  • Baseline HTML is verbose and not ideal for casual writing. Formats like Markdown and AsciiDoc are widely used because they're simpler to read and write for human beings. While semantic HTML addresses the readability issue, it does nothing to address the repeatability issue.

There are many ways to build a static site based on your needs and the language you're comfortable with. But they follow two basic approaches.

Approach 1: Use a site builder

A site builder is the quickest way to get up and running. They usually come with themes included, and can render formats like Markdown or AsciiDoc into plain HTML. They often have config options for common setups (like Google Analytics) and plugins to help with deploying and optimising content.

They're easy to use and quick to deploy, but site builders can be inflexible. Most can only build sites in a blog-like setup, and unless you want to write your own theme you might be stuck choosing between imperfect templates. Site builders are available in a variety of languages, depending on your preference.

Some popular site builders include:

This site is written in Pelican because my language of choice is Python, because it renders Markdown files, and because I was already familiar with Jinja, its template language.

Approach 2: Build with a template language

This option is closer to developing a website from scratch. It takes longer, but you get a lot more flexibility.

A template language lets you build HTML pages yourself. You can usually embed different components in a larger template, and use logic like if statements and loops to generate parts of webpages. You can then write a short script in your programming language of choice to build the static site of your dreams.

There are several popular template languages:

  • Jinja - the default with Flask. Also commonly used with Django and other Python projects.
  • EJS - the original Javascript templating language.
  • Mustache - probably the most popular templating system. Available in a variety of languages.
  • Liquid - an originally Ruby-based templating approach, created and used by Shopify.

Web Host and CI/CD

When choosing a web host for your static site you probably want the cheapest, fastest, and best.

The key is not to use a server. Instead, you want to serve your site on the edge. You can achieve this with providers like Vercel or Netlify. If you prefer to be more hands-on you can use AWS S3 buckets via Amazon Cloudfront. Github pages is also a good choice but requires a paid subscription for some features. This site is deployed on the Vercel network as it's easy to use and currently free for static sites with custom domain names.

In all cases, you're uploading your site's assets to a CDN (content distribution network). This is a network of hundreds of servers worldwide which hosts your static content. Because static sites don't need complex infrastructure, they can be hosted cheaply - all the CDN needs to do is deliver a few HTML files and images to clients on demand. Because they're close to the user, they deliver content fast globally.

To push updates from your computer to a CDN automatically, you need a code repository with a CI/CD set up. If you chose Vercel or Netlify, they have integrations with Github and Gitlab built in, meaning you don't need to worry about exactly how your code gets pushed to those networks. If you chose AWS, then you'll need to use a Github Actions workflow or similar to build your site and upload its content to the bucket.

The specifics vary, but deployments take three steps:

  1. Push your source code to a repository
  2. Build the site using your site builder or template engine
  3. Push the new static content to your CDN

You'll need to configure some options on your hosting provider to get your static content to show correctly. For example, Vercel has an option for 'pretty routes' which turns urls like example.com/page.html into example.com/page, which was needed for Pelican to link pages successfully.

Interactions and Analytics

You always have Javascript available to you. You can write code to do everything that's possible in a more complex setup, like displaying modals and burger menus, in the same way on a static site.

But since there's no server backing your website, you can't build a backend 'app'. But that doesn't mean you can't build interactions or forms.

We can use the Islands Architecture to build out webpages with interactive elements. There are two basic ways of achieving this:

  • Use third-party services to provide interactivity
  • Write edge functions to provide a lean backend

Third-party services range from integration platforms like IFTTT to comments plugins like Disqus. They're the fastest way to get the functionality you want, but they can be expensive for the value they provide. (This doesn't include IFTTT, which I think is great value.)

Another solution is to write your own edge functions. These are small snippets of code which, like your website, are hosted on an edge network of servers. Netlify, Vercel, and AWS all have their own versions. You can use edge functions to do a lot of basic backend tasks, from managing uploads to taking form submissions. With Turso it's even possible to host databases on the edge.

It's often helpful to know how many people are visiting your site, especially if it's something like a blog. Luckily, common analytics solutions like Google Analytics can easily be embedded into the <head> tag of your site by modifying your templates or through some configuration option in your site builder.

Conclusion

Static sites are fast and cost-effective ways to reduce the time between writing an article and publishing it. With a good setup you can type out an article and put it online in a couple of hours. This kind of pace is normally restricted to full-time writers like journalists.

By deploying to an edge network, static sites can be as fast as solutions costing hundreds of dollars a month - for free.

My current workflow looks like:

  • Write a draft in Markdown
  • Edit it into a second draft
  • Add images and correct formatting
  • Push it to Github

The Vercel integration and build commands take care of the rest, and content comes online as little as a minute after I push it.

If you want the benefits of speed and ease of publishing, perhaps you should give static sites a try.

If you're interested in tutoring, click here.