From dd515abc41c321f1cdd794dc773b11e97f315d95 Mon Sep 17 00:00:00 2001 From: Vivek Date: Thu, 30 Jul 2026 15:38:12 +0530 Subject: [PATCH] fix: write the footer brand credit as WebJs, not lowercase Invariant 11 capitalizes the brand wherever it names the project in prose, reserving the lowercase form for literal code tokens (a CLI command, the domain, an @webjsdev package, a config key, an env var). The footer credit was prose, so it should always have read "Built with WebJs". It renders on every page, which made it the most-viewed instance of the name written wrongly, and it contradicted the scaffold, which already emits the capitalized form (packages/cli/lib/create.js L1384). Add the SSR assertion alongside it. The edit-time hook that enforces casing only scans NEW content, so a string already in the tree is never re-checked and CI has no equivalent, which is exactly how this survived. The test also pins the comparison hrefs as lowercase, so a later over-eager fix cannot "correct" the url paths and break those links. Counterfactual verified: reverting the source line fails the new test on the brand-casing assertion specifically. Closes #1190 --- website/lib/ui/site-footer.ts | 2 +- website/test/ssr/nav-and-routes.test.ts | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/website/lib/ui/site-footer.ts b/website/lib/ui/site-footer.ts index 1912a360c..0244294f1 100644 --- a/website/lib/ui/site-footer.ts +++ b/website/lib/ui/site-footer.ts @@ -61,7 +61,7 @@ export function siteFooter() {
MIT License${NEW_TAB}
-
Built with webjs
+
Built with WebJs
diff --git a/website/test/ssr/nav-and-routes.test.ts b/website/test/ssr/nav-and-routes.test.ts index a6c755c06..bbf71be25 100644 --- a/website/test/ssr/nav-and-routes.test.ts +++ b/website/test/ssr/nav-and-routes.test.ts @@ -77,3 +77,23 @@ test('no internal link still points at the old /why path', async () => { assert.ok(!/href="\/why"/.test(out), 'no chrome link targets the pre-rename path'); } }); + +test('the footer writes the brand name with proper casing', async () => { + // Invariant 11: WebJs is capitalized wherever it NAMES the project in prose, + // and the lowercase `webjs` form is reserved for literal code tokens (a CLI + // command, the domain, an `@webjsdev` package, a config key, an env var). + // The footer renders on EVERY page, so a slip here is the most-viewed + // instance of the brand name on the site, and it shipped that way once + // already (#1190). + // + // The edit-time hook that enforces casing only scans NEW content, so a string + // already in the tree is never re-checked and CI has no equivalent. This test + // is that missing check, scoped to the one surface that matters most. + const out = await renderToString(siteFooter()); + assert.ok(out.includes('Built with WebJs'), 'footer credits the brand with proper casing'); + assert.ok(!/Built with webjs/.test(out), 'and never the lowercase code-token form'); + + // Route paths are NOT prose and must stay lowercase, so guard against an + // over-eager fix that "corrects" the hrefs and breaks every comparison link. + assert.ok(out.includes('href="/compare/webjs-vs-nextjs"'), 'url paths stay lowercase'); +});