@alphablue/site-runtime
v0.1.0
Published
Edge injection of AlphaBlue live site state for Cloudflare Pages and Workers.
Readme
@alphablue/site-runtime
Edge injection of live site state for statically built sites on Cloudflare.
A static site has no code on the request path, so state that must take effect without a rebuild — a mourning grayscale, an announcement bar — has nowhere to be applied. This library provides the one place it can be: between the static asset and the browser, rewriting the built HTML as it streams.
Most sites will not use this directly. It is generated for you by
@alphablue/astro-site.
Why not client-side JavaScript
Grayscale applied by a script means the browser paints the site in full colour first and greys it once the script arrives. For most features that is a blemish. The occasion for this one is royal mourning or a national disaster, where a flash of colour is a public discourtesy — and where a script that fails to load fails silently, with nobody finding out.
HTMLRewriter puts the attribute on the very first tag of the document, so the
browser knows before it has parsed anything else.
Usage
Cloudflare Pages
// functions/_middleware.ts
import { applyLiveState } from "@alphablue/site-runtime";
export const onRequest: PagesFunction<Env> = async (ctx) =>
applyLiveState(await ctx.next(), ctx.env);Workers Static Assets
Use fetchAsset rather than env.ASSETS.fetch — see below.
// worker/index.ts
import { applyLiveState, fetchAsset } from "@alphablue/site-runtime";
export default {
async fetch(request, env) {
return applyLiveState(await fetchAsset(request, env), env);
},
} satisfies ExportedHandler<Env>;Both hosts need a LIVE_STATE KV binding and a SITE_ID var, and the site's CSS
needs one rule:
html[data-mourning="1"] { filter: grayscale(1); }Exported as MOURNING_CSS if you would rather inject it.
fetchAsset, and why it exists
Workers Static Assets sends an ETag for every file. State is applied after the
asset is fetched, so a returning visitor's If-None-Match gets a 304 with no
body — nothing to inject into — and their browser keeps showing the cached colour
version. fetchAsset strips conditional validators from navigations only, so
assets keep their caching.
Cloudflare Pages sends no validators for HTML, so this is unnecessary there.
Failure behaviour
If the KV read fails, the original response is returned untouched. This code runs in front of every page of every site using it; a content-service problem must not be able to take those sites offline.
License
MIT
