ReviewOS

stacks/uplink

fix(homepage): a 51 KB router ships against the file's no client script note

#30
Open glennmichael123 opened this 8 days ago ·
8 days ago

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-L13 states 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> at resources/views/index.stx#L1 is 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 with cache-control: public, max-age=31536000, immutable.
  • Nothing in the repository asks for it. config/ui.ts#L9-L69 is the whole stx config and sets no router key. The values come from node_modules/bun-plugin-stx/dist/serve.js#L10291-L10300, where getRouterInjectOptions() hardcodes interceptAllLinks: true and container: 'main' and then spreads siteConfig?.router over them at #L10297 and stxConfig.router at #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 on at resources/views/index.stx#L183, #L198 and #L322 get a full navigation. downloadUrl is release.url at resources/views/index.stx#L49, which is the GitHub URL at resources/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, #how at resources/views/index.stx#L181 and #L202 and #questions at #L182, plus the logo at #L176 pointing at /, which is this same page. The bundle loaded for that carries prefetching, a pushState history layer and a layout cache.
  • Turning the injection off is not a config flag today. StxOptions is Partial<StxConfig> at node_modules/@stacksjs/stx/dist/types/config-types.d.ts#L975 and StxConfig declares router.enabled at #L885-L886, so config/ui.ts can legally write it, but the serve path never reads it. The injector at node_modules/@stacksjs/stx/dist/chunk-2cey22m2.js#L3527 copies container, interceptAllLinks, progress, viewTransitions, scrollToTop, prefetch and cache out of the options and has no enabled branch, and node_modules/bun-plugin-stx/dist/serve.js#L10246 calls 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#L152 defines .u-code and #L153 defines .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

  1. Set router: { interceptAllLinks: false } in config/ui.ts. stxConfig.router is spread last at node_modules/bun-plugin-stx/dist/serve.js#L10298, so this reaches the injected config block and stops the page claiming every same-origin anchor.
  2. 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/stx to honour router.enabled === false where the injector runs, or have resources/views/index.stx emit 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.
  3. Reconcile resources/views/index.stx#L12-L13 with 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.
  4. Delete resources/views/index.stx#L152 and #L153, or give them an element to style. The only command string on the page is claude setup-token at #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 of curl -s https://uplink.stacksjs.com/ after the deploy step at .github/workflows/deploy.yml#L185 has run.
  • Do not match on the router filename. /_stx/router.857e342153156d57.js is content hashed and the hash moves when the dependency moves. Match on data-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. #how and #questions must still scroll, and scroll-mt-16 on the two sections at resources/views/index.stx#L240 and #L356 must 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.ts and resources/views/index.stx. No new routes and no new views.
  • Leave the /404 status 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' returns 0. If the upstream fix did not land in time, the bundle is still there but window.__stxRouterConfig.interceptAllLinks is false and resources/views/index.stx#L12-L13 has 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 lint passes and ./buddy typecheck passes, since step 1 adds a key to config/ui.ts.

Sign in to comment on this issue.