Case study · our own

We run this site on Azure Static Web Apps. Here is exactly how, and what it costs.

No client permission needed for this one: the client is us, the system is the page you are reading, and every number below is something you can re-check yourself.

production Lighthouse/CWV measurement due

javascript shipped, content pages

0 KB

Measured in the built output — PROGRESS.md

Open dev tools on this page and you will find 0 KB of JavaScript: the nav is a details element, the FAQ is a details element, the motion is CSS, and there is no framework runtime to ship.

What's actually running

This site is a static Astro build, checked into git, deployed to Azure Static Web Apps by GitHub Actions. There is no server rendering anything on request, no database, and — on every content page — no client-side JavaScript at all. The table is every load-bearing fact about the stack, as it stood on the day this page was written.

What's actually running, as of the last build
LayerWhat it isDated
FrameworkAstro 7, static output, zero client JavaScript by defaultSTACK.md §3.4, 2026-08-17
HostingAzure Static Web Apps — Free plan, $0/monthSTACK.md §0, 2026-08-17; provisioned 2026-08-18
DeployGitHub Actions, on every push to main, with a preview URL per pull requestDEPLOY.md §3, 2026-08-17
JavaScript shipped0 KB on content pages, in the built outputPROGRESS.md, 2026-08-18
CSS5.5–6.6 KB gzip per pagePROGRESS.md, 2026-08-18
Fonts42.2 KB total across 2 self-hosted WOFF2 files (IBM Plex Sans + Mono)src/assets/fonts/README.md, 2026-08-18
Monthly Azure spend$0, with a $5/month budget alert as the smoke alarmDEPLOY.md §11.1, PROGRESS.md, 2026-08-18

The apex-versus-www split above is deliberate, not an accident of DNS: it is the one item in the not-fixed list below that is a platform constraint rather than a choice.

The mechanism, since the score doesn't exist yet

This site has not gone live at www.asdataworks.com yet, so there is no real, measured production Lighthouse or Core Web Vitals score to show. We would rather show nothing than a staging number wearing a production label.

What exists today, honestly, is a gate in two parts. The part that is real and already blocking merges: every pull request runs a typecheck and the token-contrast/design-system rule tests before it builds, and a failing check stops the merge — verifiable by reading.github/workflows/deploy.yml. The part that is designed but not yet wired up: a required Lighthouse-budget check (mobile Performance ≥95, Accessibility 100, SEO 100), an accessibility pass, a broken-link/orphan check and the hreflang-pair validator — all specified in this site's own build documents, and named as an open TODO in that same workflow file rather than quietly assumed. We are naming the gap instead of describing the finished mechanism as if it already existed.

How it is actually built and shipped

The same five steps run for every change, whether it is a typo fix or this page.

  1. Write. Every page and every template lives as a component or a Markdown-shaped file in this repository. Nothing is hand-edited on a server, and nothing renders that is not in git.

  2. Open a pull request. Azure Static Web Apps generates a real preview URL for every PR, so a reviewer looks at the actual rendered page before anything merges — not a diff.

  3. CI gates the merge. A typecheck and the token-contrast/design-system rule tests run before the build, and a red check blocks the merge — it is not overridden. The fuller gate set (Lighthouse budgets, an accessibility pass, a link/orphan check, the hreflang-pair validator) is designed and documented, and is not wired up as required checks yet — see below.

  4. GitHub Actions deploys on merge. Azure's static-web-apps-deploy action uploads the build to the Static Web App the moment main changes — a one-to-three-minute run, visible in the Actions tab.

  5. Azure Static Web Apps serves it. The Free plan puts www.asdataworks.com on Azure’s global edge at $0/month, with a $5 budget alert standing in as the smoke detector for anything that starts costing money.

What is not fixed — and one thing that briefly wasn't

Four things, in the order we found them, none hidden:

The Lighthouse/accessibility/link CI gates are not wired up yet

The design decided a Lighthouse-budget check, an accessibility pass, a broken-link/orphan check and the hreflang-pair validator as required status checks before any PR can merge. Today's real pipeline runs a typecheck, the token-contrast/design-system rule tests, and the build — the rest is a named TODO comment in the workflow file, not a silent gap. This page's own "mechanism" section above says so plainly rather than describing a finished gate that does not exist yet.

.github/workflows/deploy.yml

The apex domain is a single-region A record

asdataworks.com (no www) resolves through a single-regionA record rather than a globally distributed edge, because the domain's DNS is Microsoft-hosted from the M365 admin center, and that surface offers neitherALIAS/ANAME records nor CNAME flattening — the two mechanisms Azure Static Web Apps needs to put an apex domain on its global edge properly.www.asdataworks.com is the canonical host and carries all real traffic on the full edge; the apex exists only to redirect to it, and pays the single-region penalty on that one redirect hop, once per visitor session.

STACK.md §2

There is no SLA on the Static Web Apps Free plan

We are selling reliability and running our own marketing site on a plan that carries no service-level agreement. That is a real, accepted trade against $9/month for the Standard plan's SLA, made because the operational load at this traffic and this team size does not currently justify it. The trigger to upgrade is written down rather than left to feel: the first of paid traffic going live, a third custom domain being needed, or a client contract requiring us to state an SLA for our own web presence.

STACK.md §1.4

The sans font briefly missed its own budget

For part of one build day, the self-hosted variable sans font shipped unsubset — the full weight 100–700 axis, at 45.7 KB — before axis-instancing and a Latin-only feature-prune brought it down to 27.5 KB the same day. It never breached the sitewide font ceiling (55 KB across both files together), but for that window it ran heavier than the 34 KB we had budgeted for that one file. We are noting it because "we caught it and fixed it the same day" is a real thing worth disclosing, not because it is still true.

src/assets/fonts/README.md

Start with the assessment, not the migration.

Book an assessment call

30 minuteswith the engineer who would scope the work[PLACEHOLDER: written-summary turnaround, not yet committed]