How it's built
Every number on this sheet comes from this build or from your own request. None of it is typed by hand.
1 · Your request, up close
How this page reached you
Connecting…
- Last deploy
- 9 Oct, 07:58 am IST, from main
- Visits today
- –
- Pipeline
- git commit · main → wrangler deploy
Revision4.7
Builde18db25
Statusstatic
2 · How it got here
git commit · main → wrangler deploy
3 · What shipped with this build
- e18db25Declare font-stretch: 100% on the local font faces, as Google's CSS did9 Oct 2026
- 49fdabaKeep the font fallback sizes next/font/google used9 Oct 2026
- 275f65cServe fonts from the repo instead of fetching Google Fonts at build9 Oct 2026
- 8a74a6fUpdate wrangler to 4.149.09 Oct 2026
- 5a84927Build before typecheck and tests in CI9 Oct 2026
- 04cc497Use the patelaryandev GitHub account9 Oct 2026
- 4e2f003Move the site to patelaryan.dev9 Oct 2026
- 0cf1b80Use the <a> favicon (07-anchor) as the live icon8 Oct 2026
- 1eb71d9Move favicon gallery into the preview deploy folder8 Oct 2026
- 6496776Add 10 alternative favicon sets with a preview gallery8 Oct 2026
4 · What the homepage weighs
- HTML
- 5.0 KB
- CSS
- 3.2 KB
- JavaScript
- 137.9 KB of a 150.0 KB budget
- Fonts (preloaded)
- 91.6 KB
- Total, gzipped
- 237.6 KB
the build fails if JavaScript goes over budget
5 · The Worker, annotated
const NO_STORE = { 'cache-control': 'no-store' };
const json = (body: unknown, status = 200, headers: Record<string, string> = {}) =>
new Response(JSON.stringify(body), { status, headers: { 'content-type': 'application/json', ...NO_STORE, ...headers } });
export const utcDay = (d: Date) => d.toISOString().slice(0, 10);
// The browser times this round trip. It never counts as a visit.
export function handlePing(req: Request): Response {
if (req.method !== 'HEAD' && req.method !== 'GET') return json({ error: 'method not allowed' }, 405, { allow: 'GET, HEAD' });
return new Response(null, { status: 204, headers: NO_STORE });
}
export async function handleVisit(
req: Request,
hit: (day: string) => Promise<number>,
build: { sha: string; time: string },
now = new Date(),
): Promise<Response> {
if (req.method !== 'GET') return json({ error: 'method not allowed' }, 405, { allow: 'GET' });
const colo = (req as Request & { cf?: { colo?: string } }).cf?.colo ?? null;
let visitsToday: number | null = null;
try {
visitsToday = await hit(utcDay(now));
} catch (err) {
console.error('visit counter failed', err); // the panel shows "–"; the rest still works
}
return json({ colo, visitsToday, build });
}
export const notFound = () => json({ error: 'not found' }, 404);show all 31 linesshow less
import { DurableObject } from 'cloudflare:workers';
import { nextCount, type DayCount } from './counter';
// One global instance. Durable Object storage is strongly consistent, so two
// visits at the same moment never overwrite each other's count.
export class VisitCounter extends DurableObject {
async hit(day: string): Promise<number> {
const next = nextCount(await this.ctx.storage.get<DayCount>('today'), day);
await this.ctx.storage.put('today', next);
return next.count;
}
}6 · Decisions
- Chose A static export over a Next.js server, because every page is the same for every visitor, so plain files are faster and have nothing to patch.
- Chose Cloudflare Workers over Pages, because one deploy serves the files and the two small APIs, and it is where Cloudflare is putting new features.
- Chose A Durable Object over KV, because KV is eventually consistent, so two visits at once could lose a count; a Durable Object cannot.
- Chose Plain CSS over a CSS framework, because the design has a handful of components, and tokens in custom properties cover them.
- Chose A native <details> toggle over a JS accordion, because the code is readable with JavaScript off and ships zero bytes of script.
Drawn byA. Patel
Revision4.7
Builde18db25
Sheet2 / 2