Skip to content

The site is a build, published at thankywal.github.io/muxel - #39

Merged
thankywal merged 2 commits into
mainfrom
site-on-github-pages
Sep 6, 2026
Merged

The site is a build, published at thankywal.github.io/muxel#39
thankywal merged 2 commits into
mainfrom
site-on-github-pages

Conversation

@thankywal

@thankywal thankywal commented Sep 6, 2026

Copy link
Copy Markdown
Owner

The console, the product page and the guide were served by an express process on a VPS, and the address every document sent a new owner to was app.muxel.site. That domain is going to another project, so both had to move.

The site is files

scripts/build-site.mjs writes the whole site, and GitHub Pages serves it:

/muxel/                      the console
/muxel/product/              what Muxel is
/muxel/docs/                 the guide, English
/muxel/docs/{my,th,ja,zh}/   the other four languages
/muxel/docs/{deploy-recovery,telegram-setup}/
/muxel/docs/media/           the pictures the READMEs show
404.html → the product page

The console is the site, not a page of it. It used to be chosen by hostname — app.muxel.site was the console and muxel.site was the product page — and the hostname that chose it is the one leaving. That is free: the console has no router, no history and no hash. Nothing in it reads the URL.

One record for the address

app.muxel.site was typed out in seventeen places — the Worker's own first screen, four languages of Telegram strings, the assistant's description of itself, the command line, two deploy scripts, the console's HTML — and in five READMEs besides.

CONSOLE_HOME now lives in @muxel/core, because the programs that name it cannot all import each other. The translations take it as a {console} variable rather than four copies of a sentence. The files that cannot import anything — the READMEs, the deploy scripts, the console's HTML — are held to the same value by a test.

The base path

A project site lives under /muxel/, a custom domain lives at /. The workflow reads that from GitHub (configure-pagesbase_path) rather than deciding it here. Every root-absolute URL is moved onto that base on the way out, and what may be moved is the set of names the build actually emits — a link to something that is not there cannot be quietly repointed, and one nobody taught the build about fails it.

Two bugs the new test found

  • An open bracket in the URL pattern ate text.replace(/docs/g, x) — a regular expression in JavaScript starts exactly the way a path does. It was one root name away from corrupting app.js.
  • A link to the top of the site has no path segment to be recognised by, so href="/" was left pointing at thankywal.github.io/ rather than at the site. A lone slash is every split and every join, so only an attribute counts.

One site, two places it can be put

server.mjs now serves what the build wrote instead of building on demand, so the copy it hands a browser and the copy Pages hands a browser are the same bytes. It answers exactly as Pages does: /docs → 301 → /docs/, unknown paths → 404.html.

Verified

  • 933 tests (83 files), build, typecheck, lint, worker bundle — all pass
  • Built at both bases and driven in headless Chrome: every page 200, no console errors, no failed requests, no broken images
  • Every internal link the built site makes — all 19 — resolves 200
  • server.mjs against the root build: /, /product/, /docs, /docs/, /docs/my/, /app.js, /notice.json correct; /nope → 404

Also

.dev.vars.example still offered "live web search, reading a document as data" — both removed at revision 20.


Merging this turns GitHub Pages on (enablement: true) and publishes the site at https://thankywal.github.io/muxel/. Nothing is removed from the VPS by this PR.

🤖 Generated with Claude Code

https://claude.ai/code/session_01LoYEEHLJc4CifTLHjKpcDF

thankywal and others added 2 commits September 6, 2026 12:53
The console, the product page and the guide were served by an express
process on a VPS. Everything that process did which needed a process was
rendering the README into the guide, and that can happen once, at build
time. The machine it ran on was the last thing in Muxel's own path that
an owner had to trust for a page which, by design, talks to nothing but
their own Worker.

scripts/build-site.mjs writes the whole site as files: the product page
at the root, the console at /console/, and the guide in five languages
plus the two documents the READMEs link to. The hostname the old process
used to pick between the product page and the console becomes a path,
which is free because the console has no router, no history and no hash —
nothing in it reads the URL.

The base path is the one thing that differs between hosts: a project site
lives under /muxel/ and a custom domain lives at /. The workflow reads it
from GitHub rather than deciding it here, so pointing a domain at this
later changes nothing in the repository. Every root-absolute URL the site
uses is moved onto that base on the way out, and what may be moved is the
set of names the build actually emits — a link to something that is not
there cannot be quietly repointed, and one nobody taught the build about
fails it.

server.mjs now serves what the build wrote instead of building on demand,
so the copy it hands a browser and the copy Pages hands a browser are the
same bytes rather than two renderings that can drift.

The build's own test found one bug worth naming: an open bracket in the
URL pattern ate `text.replace(/docs/g, x)`, because a regular expression
in JavaScript starts exactly the way a path does.

Also: .dev.vars.example still offered live web search and reading a
document as data, which were removed at revision 20.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LoYEEHLJc4CifTLHjKpcDF
app.muxel.site was typed out in seventeen places — the Worker's own first
screen, four languages of Telegram strings, the assistant's description of
itself, the command line, two deploy scripts, the console's own HTML — and
in five READMEs besides. The domain is going to another project, so all
of it had to move, which is exactly the change seventeen copies of a
string make expensive.

CONSOLE_HOME lives in core, because the programs that name it cannot all
import each other: the Worker puts it on its first screen, the command
line prints it after a deploy, and the console links back to it. The
translations take it as a variable rather than four copies of a sentence.
The files that cannot import anything — the READMEs, the deploy scripts,
the console's HTML — are held to the same value by a test, because a
document that sends an owner somewhere empty is worse than one that says
nothing at all.

The console becomes the site rather than a page of it. It used to be
chosen by hostname, and the hostname that chose it is the one leaving, so
https://thankywal.github.io/muxel/ is the console and the product page
moves to /product/, where the console's footer and an unknown path both
still reach it.

The build learned about the top of the site on the way: a link to it has
no path segment to be recognised by, and a lone slash is far too common in
code to rewrite on sight, so only an attribute counts.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LoYEEHLJc4CifTLHjKpcDF
@thankywal thankywal changed the title The site is a build, and GitHub Pages serves it The site is a build, published at thankywal.github.io/muxel Sep 6, 2026
@thankywal
thankywal merged commit 9a13dce into main Sep 6, 2026
2 checks passed
@thankywal
thankywal deleted the site-on-github-pages branch September 6, 2026 06:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant