Split The code is public; the app answers only to the crew.

JavaScript off: a menu of dead buttons and not one word saying why #220

shipped merged opened this has it
opened this

Tell a visitor whose browser will not run the game what happened, in the page the server already renders.

grep -rn noscript src finds nothing, and the served page has 27 <button>s and two <canvas>es. So a visitor with scripting blocked - a locked-down work laptop, a privacy extension, a bundle that 404s behind a proxy - gets the full menu: Play, Map, Difficulty, Fullscreen, all of it rendered and all of it dead. Every click does nothing and the page never says a word. The leaderboard below it works, which makes it worse: the page looks alive.

The pattern to copy is already in the repository. main.ts:100 handles the other half of this exactly right: no WebGL2 and the menu is replaced with <h2>No WebGL2</h2><p>This browser cannot run the game. Everything else on the page still works.</p>. That is the sentence and the tone; it just cannot run when the script itself never runs.

Done looks like

  • [ ] A <noscript> block in src/pages/game.ts that a scripting-off visitor sees where the menu is, in the page's own voice: this needs JavaScript and WebGL2, the board below still works. No new page, no redirect.
  • [ ] The controls that cannot work are not offered as if they could: with scripting off the menu's buttons are hidden or visibly disabled, driven by CSS the <noscript> block turns on - no script required to reach that state, and no flash of dead buttons before it applies.
  • [ ] No layout shift for the normal visitor: with scripting on, the block renders nothing and occupies nothing. State in the pull how you checked.
  • [ ] The CSP is unchanged. style-src 'self' 'unsafe-inline' already allows the page's own inline sheet, so this needs no new directive and no new external file.
  • [ ] Tests in src/pages/game.test.ts: the served HTML contains the <noscript> block and its sentence, and the rule that disables the menu is in the sheet. Keep it to what the string says - this is a server-rendered page and its test is a string test.
  • [ ] bun run check green.

Files I expect to change

  • src/pages/game.ts, src/pages/game.test.ts.

Risks

  • Do not hide the leaderboard: it is the half of the page that works without a script, and saying so is the point.
  • <noscript> inside <head> may only contain link/style/meta; this belongs in the body, next to the menu it is about.
  • Adjacent but not this: #206 adds the icon and the manifest. Keep that out of here.

Crew

scout - the server-rendered page and its string tests.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs