Back to Blogs

Live Configs in "Static" sites

A case study on how I made a Docker-ready image that serves a website with zero javascript packaged, but still has a live configuration.

architecture
Live Configs in "Static" sites

Published on Feb 24, 2026

Updated on Feb 24, 2026


Whoo, it’s been a hot minute since I took on a commission. My friend, who is a tech administrator and also the community ambassador of the trans-identities community, reached out to me for a simple configurable landing page for her March launch.

You can check out her community here. You can also commission me here, wink ;)

Requirements Analysis (it had a term for it apparently)

I did not know this process that I have been doing all my life has a specific term for it, called Requirements Analysis. Ironically, this is the process that is severely lacking in my capstone project, leading to a development team that can’t agree with each other on anything.

For this project, the client seems to want the following:

  • Configuration: She breathes Docker and configurations, but she doesn’t code herself. It needs a way for her to tweak the content, without having to touch the source code or the container even after deployment.
  • Fits her budget: Usually, the client would need to commission a designer or a design agency, gets their designed framework. Then commission a separate developer, and have the design be built up. She took advantage of me knowing certain parts of design and development, and got a budget-fitting quote for a lightweight landing page.
  • It IS a landing page: Let’s not complicate everything with React or MERN stack everyone yaps about. It’s a content page first and foremost, and she would love for it to show up on search engines.

I settled on AstroJS, but using the standalone SSR module, for the following reasons:

  • The configuration needs hot reload. SSR allows Astro to build a landing page at the time of request. She doesn’t need to rebuild the image or reload the container to have the landing page’s content change. (Wowie)
  • Astro uses a zero JS delivery by default. The user should not have to download a bunch of React runtimes just to view some content! I like React, but the prevalence of it for simple things like content websites are way too bad.

Static vs Dynamic Websites

Something I noticed is that a lot of people don’t understand the blurry lines between what you would consider a static website and a dynamic website, and to be honest, I don’t either because I don’t think everyone agreed on a solid definition. A good way to think about it is about how the page is built and delivered.

TechnologyThe browser receivesLike a?Pros & Cons
SSGFull HTMLFrozen PizzaFastest, can be put on a S3 or CDN. But you need to recook (rebuild) every time you change a piece.
Partial HydrationSkeleton HTML + JS to get contentDIY Pizza KitSlowest, but can be on a S3 or CDN. The browser has to assemble the pizza before you can eat.
SSRFull HTMLRestaurant MealFast, can’t be on a S3 or CDN*. A cook cooks a pizza when you need it, hot.

Implementing the Live Config

To give her that nice configuration, I used js-yaml and zod. By using schema.safeParse, I ensured that if she makes a typo in the YAML, the site doesn’t just crash silently but it catches the error (and also calls her a dumbass but who cares).

import yaml from "js-yaml";
import fs from "fs";
import z from "zod";

const filePath = process.env.CONFIG_FILE || `${process.cwd()}/config.yml`;

const schema = z.object({
  ...
});

type ConfigSchema = z.infer<typeof schema>;

export { type ConfigSchema };

export function loadConfig() {
  const data = yaml.load(fs.readFileSync(filePath, "utf8"));
  return schema.safeParse(data);
}

The z.infer is to allow TypeScript and vstls (I think I spelled that right) can auto-complete typenames.

The Markdown Compromise

Usually, you’d expect users to configure just raw text, because that’s the easiest thing to monitor, and you wouldn’t have to care about edge cases, since raw text easily wraps around in modern browsers. The problem here is that it’s not as customizable with raw text, as the client wants some level of bolding, and linking in the content. Thankfully, she is very happy with Markdown.

Retrospective

What we couldn’t do

This is a short retrospective section of the commission as a whole. There were a few things that were dropped from the final product, due to some issues with several requirements, as well as being rather out of scope for the March launch.

The February 11th deadline was tight, especially with Lunar New Year falling right in the middle (Feb 17). Between visiting my father’s hometown and a trip with my mother, the “dev window” was tiny. (There are a lot of responsibilities that comes with being the eldest sister in the family). We had to drop a few:

  • A cycling version of the logo. I’d love some decorative scripting that doesn’t affect the entire page too much, so noscript users still can enjoy the content.
  • A CSS-based infinite carousel. It seems like it doesn’t matter what you do, the infinite carousel WILL look wrong in a certain resolution, a certain zoom size, a certain DPI, or a certain laggy machine.
  • A live player count indicator and some self-made drawing. I’d love to draw some silly indicators for a player count, but it seems like her game server kept going down, and didn’t really have a way to grab a player’s count from outside, so we put that as “Out of Scope”.

What we could

But overall, we were able to complete some rather cool features that she was happy with:

  • Full HTML content delivered on request, with very low JS footprint. Even a person using NoJS extension can still access the page mostly, just no animations.
  • A live config that when edited, affects all subsequent HTML generations.
  • All deployable with Docker, with no installation needed on the host.

I think that works rather well, or maybe I’m not as good to make it better yet. I didn’t want to rely on React or crazy amount of animations or interactivity, maybe this philosophy fit the client’s needs for accessibility for her diverse community.


🌸

Similar Blogs