Part of #6.
The header comment at the top of resources/views/index.stx is the only record of how this page is meant to behave, and the next person to edit it will read that comment rather than the deployed HTML. Today the two disagree and nothing in the repository says so. The same file also carries two CSS rules that no element matches, which is the smaller half of the same drift: what is in the source and what is served have come apart.
What is there today
resources/views/index.stx#L12-L13states the page's own invariant: "No client script: motion is CSS only, and every animation has a reduced-motion fallback."- The source honours it.
<script server>atresources/views/index.stx#L1is the only script tag in the file, and it runs at render time. - The served page does not.
https://uplink.stacksjs.com/ends with<script>window.__stxRouterConfig={"container":"main","interceptAllLinks":true};</script>followed by<script data-stx-router src="/_stx/router.857e342153156d57.js"></script>. That bundle is 50,926 bytes uncompressed, 12,839 bytes over the wire as brotli, served withcache-control: public, max-age=31536000, immutable. - Nothing in the repository asks for it.
config/ui.ts#L9-L69is the whole stx config and sets norouterkey. The values come fromnode_modules/bun-plugin-stx/dist/serve.js#L10291-L10300, wheregetRouterInjectOptions()hardcodesinterceptAllLinks: trueandcontainer: 'main'and then spreadssiteConfig?.routerover them at#L10297andstxConfig.routerat#L10298. Both stx packages are at 0.2.320. - The cross-origin case is already safe. The bundle guards with
if(t.origin!==location.origin){location.href=url;return Promise.resolve(false)}, so the three download links onatresources/views/index.stx#L183,#L198and#L322get a full navigation.downloadUrlisrelease.urlatresources/views/index.stx#L49, which is the GitHub URL atresources/data/release.json#L5. - What is left for the router to do is almost nothing. The page's only same-origin links are three in-page anchors,
#howatresources/views/index.stx#L181and#L202and#questionsat#L182, plus the logo at#L176pointing at/, which is this same page. The bundle loaded for that carries prefetching, apushStatehistory layer and a layout cache. - Turning the injection off is not a config flag today.
StxOptionsisPartial<StxConfig>atnode_modules/@stacksjs/stx/dist/types/config-types.d.ts#L975andStxConfigdeclaresrouter.enabledat#L885-L886, soconfig/ui.tscan legally write it, but the serve path never reads it. The injector atnode_modules/@stacksjs/stx/dist/chunk-2cey22m2.js#L3527copiescontainer,interceptAllLinks,progress,viewTransitions,scrollToTop,prefetchandcacheout of the options and has noenabledbranch, andnode_modules/bun-plugin-stx/dist/serve.js#L10246calls it unconditionally. The one gate that does exist,spa !== false, is on the separate compile path, which is not what serves this site. - Second finding, unrelated to the router.
resources/views/index.stx#L152defines.u-codeand#L153defines.u-code .u-prompt.grep -rn 'u-code' resources/ app/ config/matches only those two lines, so a code block style from an earlier draft is inlined into every response and nothing on the page renders it.
Proposal
- Set
router: { interceptAllLinks: false }inconfig/ui.ts.stxConfig.routeris spread last atnode_modules/bun-plugin-stx/dist/serve.js#L10298, so this reaches the injected config block and stops the page claiming every same-origin anchor. - Get the bundle itself off the page. There is no supported switch on the serve path, so pick one route and say which in the PR: open an upstream issue on
stacksjs/stxto honourrouter.enabled === falsewhere the injector runs, or haveresources/views/index.stxemit its own<script data-stx-router></script>sentinel, which the injector treats as already present and skips. The sentinel works today but is a workaround, so prefer the upstream fix if the release can wait for it. - Reconcile
resources/views/index.stx#L12-L13with whatever step 2 lands. If the bundle goes, keep the line and add one sentence naming the injection, so the next editor knows what to re-check. If the bundle stays, rewrite the line to what is true: the page writes no client script of its own, and the build appends the stx router. - Delete
resources/views/index.stx#L152and#L153, or give them an element to style. The only command string on the page isclaude setup-tokenat#L70, and it sits inside FAQ prose rather than a code block, so putting the rules to work means restructuring that answer. Deleting them is the smaller change and is fine on its own.
Requirements
- Verify on the deployed page, not in the source. The injection happens at serve time, so a grep over
resources/views/reports success whatever the fix does. Check the tail ofcurl -s https://uplink.stacksjs.com/after the deploy step at.github/workflows/deploy.yml#L185has run. - Do not match on the router filename.
/_stx/router.857e342153156d57.jsis content hashed and the hash moves when the dependency moves. Match ondata-stx-router. - State the reason accurately in the commit message. 12,839 bytes on an immutable year-long cache is not the problem. The problem is that the file declares an invariant the build breaks, and a one-page site downloads and parses a router with prefetch, history and layout-cache machinery it has no navigation to use.
- Keep the in-page anchors working.
#howand#questionsmust still scroll, andscroll-mt-16on the two sections atresources/views/index.stx#L240and#L356must still clear the sticky header at#L174. Removing the router should not change either, because anchors resolve natively, so this is a check and not work. - Touch only
config/ui.tsandresources/views/index.stx. No new routes and no new views. - Leave the
/404status code alone. It shares an audit finding with the dead CSS but belongs to the crawler issue.
Acceptance
curl -s https://uplink.stacksjs.com/ | grep -c 'data-stx-router'returns0. If the upstream fix did not land in time, the bundle is still there butwindow.__stxRouterConfig.interceptAllLinksisfalseandresources/views/index.stx#L12-L13has been corrected to describe it.grep -rn 'u-code' resources/ app/ config/returns nothing, or returns the rules plus at least one element that uses them.- On the deployed page, the three in-page anchors still scroll and all three download links still start the DMG download.
./buddy lintpasses and./buddy typecheckpasses, since step 1 adds a key toconfig/ui.ts.