You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
docs/ and packages/ui/packages/website/ are two whole npm workspaces, two Railway services, two Dockerfile stages, and two compose services that exist only to return a 301. Since #1098 and #1099 merged the documentation into website/app/docs and the component gallery into website/app/ui, neither app renders a single byte of HTML: each is one middleware.ts returning a redirect, plus a stub app/page.ts.
That work has now moved to the edge. Two Cloudflare Redirect Rules on the webjs.dev zone (46692b879a06f3a6a987b99915560393, Free plan) replace both apps:
Expression
Action
http.host eq "docs.webjs.dev"
301 static to https://webjs.dev/docs
http.host eq "ui.webjs.dev"
301 static to https://webjs.dev/ui
Both are deployed and verified: every probed URL on both hosts redirects, and no response carries x-railway-request-id, so Cloudflare answers at the edge and never contacts an origin. The two apps are now dead weight.
Design / approach
Delete both app directories and every reference to them, then let the owner remove the two Railway services.
The Cloudflare rules are a deliberate downgrade from what the middleware did, and this is accepted. The middleware was path-preserving and path-aware; the rules collapse every path onto the hub page. The owner chose the two-rule version after we measured the SEO exposure: zero third-party inbound links to either host, zero recent traffic (Railway HTTP logs empty on both services), neither subdomain in the 139-URL sitemap, and the destinations (/docs 43 URLs, /ui 33 URLs) already canonicalised and indexed. There is no ranking signal left to lose, and the seven-rule path-mapping alternative was scoped out on purpose.
Consequences the owner accepted. Do NOT re-litigate these in the PR:
ui.webjs.dev/registry/<name>.json now 301s to an HTML page. Published @webjsdev/ui 0.3.1 through 0.3.8 hard-code that URL (confirmed by unpacking the 0.3.5 tarball) and will fetch HTML then fail to parse it as JSON. 0.3.9+ resolves local-first (ui: local-first registry, on-demand example delivery, MCP ui tool #983) and is unaffected. The owner is handling this separately.
Deep paths no longer land on their equivalent (docs.webjs.dev/docs/routing goes to /docs, not /docs/routing).
Old asset URLs (ui.webjs.dev/public/og.png, referenced by already-scraped social cards) now redirect to the gallery page.
LANDMINE: do not touch packages/ui/packages/registry/
packages/ui/packages/registry/ is a DIFFERENT workspace that must stay. It holds the component sources that website/scripts/copy-registry.mjs mirrors into website/components/ui/ at build time, which the gallery detail pages (website/app/ui/[name]/page.ts) statically import. Deleting it 500s every component page in production, which is exactly regression #526. The packages/ui/packages/* workspace glob covers both, so only the website subdirectory goes.
Where to edit
In package.json L14, drop the "docs" workspace entry. The ui site rides the packages/ui/packages/* glob (L12), so that glob stays as-is.
In package.json L33, drop the "ui:dev": "npm run dev --workspace=@webjsdev/ui-website" script. Check the surrounding dev and start scripts for concurrently-style invocations referencing the docs or ui-website ports.
Regenerate package-lock.json with npm install after the workspace removal. Do not hand-edit it.
In Dockerfile, remove L52 to L56 (COPY packages/ui/packages/website/package.json, COPY docs/package.json) and L70 (COPY docs ./docs). The build FAILS on a missing COPY source, so these must go in the same commit. L124 to L125 already carries a comment about both services; update it rather than leaving a comment describing deleted things.
In compose.yaml, remove the docs service (L33 to L36, port 15002) and the ui-website service (L71 to L74, port 15003). Update the header comment at L1 to L8, which says "four services".
In .github/workflows/ci.yml, fix L37 and L53. Both loops read for app in examples/blog website docs packages/ui/packages/website and become examples/blog website. Update the step names on L35 and L51 ("blog, website, docs host, ui host"). Also review the comments at L462 to L463, L493, and L502 to L509, several of which explain why the redirect hosts are or are not covered.
Test surfaces
Delete these two, which test middleware that will not exist:
State this coverage gap plainly in the PR body rather than papering over it: the two deleted tests asserted that the redirect hosts keep resolving. That behaviour now lives in Cloudflare and CI cannot see it. Do not invent a network test against the live zone to replace them, since a CI job that fails when Cloudflare has a bad minute is worse than the gap. Note the gap and move on.
Doc surfaces (all mandatory; this is a doc-sync task as much as a deletion)
AGENTS.md L88 reads "Run webjs doctor too when you touched an in-repo app (examples/blog, website, docs, packages/ui/packages/website) ... over all four". It becomes two apps.
AGENTS.md L520, the CLI-reference paragraph naming "the redirect-only docs/ and packages/ui/packages/website/ hosts".
framework-dev.md L3 and L9, both describing the four in-repo apps and the one-image deploy.
framework-dev.md L38, the Cloudflare cache-purge section, says all four hostnames are proxied in the one zone. That stays TRUE (the hostnames still exist as redirects), but re-read it for accuracy.
README.md L153 ("all four apps at once"), L163 (the ports table row for ui.webjs.dev redirect), L173 ("Override ports when running all four"). Check for a docs.webjs.dev table row too.
website/AGENTS.md (2 refs)
.claude/skills/webjs-start-work/SKILL.md (5 refs)
Invariants to respect
Cut a worktree first (git worktree add -b <prefix>/<slug> ../webjs-<slug> origin/main); never work in the primary checkout. Enforced by .claude/hooks/require-worktree-for-edits.sh.
Run npm run worktree:link inside the fresh worktree, NOT a hand-rolled root node_modules symlink. packages/server keeps a nested ws@8 that a root-only link resolves up to ws@7, failing hundreds of assertions that never name ws.
AGENTS.md invariant 11: no em-dashes, no pause-hyphens or pause-semicolons in prose, WebJs capitalized in prose and lowercase only as a code token.
Conventional commit subject (chore: or refactor:), imperative, under 72 chars, no AI attribution.
Out of scope for this issue (owner-driven, in order, AFTER merge)
Repoint DNS. The docs and ui records currently CNAME to Railway and must become CNAME -> webjs.dev, proxied. The redirect rules fire before the origin fetch so they work regardless, but a CNAME to a deleted Railway host is fragile and can surface Error 1016 on any path that bypasses a rule.
Delete the Railway custom domains, then the services, in project webjs (1d05ab75-b64e-4920-94ef-1ca7d04778fc):
Problem
docs/andpackages/ui/packages/website/are two whole npm workspaces, two Railway services, two Dockerfile stages, and two compose services that exist only to return a 301. Since #1098 and #1099 merged the documentation intowebsite/app/docsand the component gallery intowebsite/app/ui, neither app renders a single byte of HTML: each is onemiddleware.tsreturning a redirect, plus a stubapp/page.ts.That work has now moved to the edge. Two Cloudflare Redirect Rules on the
webjs.devzone (46692b879a06f3a6a987b99915560393, Free plan) replace both apps:http.host eq "docs.webjs.dev"https://webjs.dev/docshttp.host eq "ui.webjs.dev"https://webjs.dev/uiBoth are deployed and verified: every probed URL on both hosts redirects, and no response carries
x-railway-request-id, so Cloudflare answers at the edge and never contacts an origin. The two apps are now dead weight.Design / approach
Delete both app directories and every reference to them, then let the owner remove the two Railway services.
The Cloudflare rules are a deliberate downgrade from what the middleware did, and this is accepted. The middleware was path-preserving and path-aware; the rules collapse every path onto the hub page. The owner chose the two-rule version after we measured the SEO exposure: zero third-party inbound links to either host, zero recent traffic (Railway HTTP logs empty on both services), neither subdomain in the 139-URL sitemap, and the destinations (
/docs43 URLs,/ui33 URLs) already canonicalised and indexed. There is no ranking signal left to lose, and the seven-rule path-mapping alternative was scoped out on purpose.Consequences the owner accepted. Do NOT re-litigate these in the PR:
ui.webjs.dev/registry/<name>.jsonnow 301s to an HTML page. Published@webjsdev/ui0.3.1 through 0.3.8 hard-code that URL (confirmed by unpacking the 0.3.5 tarball) and will fetch HTML then fail to parse it as JSON. 0.3.9+ resolves local-first (ui: local-first registry, on-demand example delivery, MCPuitool #983) and is unaffected. The owner is handling this separately.docs.webjs.dev/docs/routinggoes to/docs, not/docs/routing).ui.webjs.dev/public/og.png, referenced by already-scraped social cards) now redirect to the gallery page.Implementation notes (for the implementing agent)
Delete these two directories
docs/, the workspace@webjsdev/docs-redirect(holdsmiddleware.ts,app/page.ts,public/tailwind.css,package.json,tsconfig.json,AGENTS.md,CLAUDE.md)packages/ui/packages/website/, the workspace@webjsdev/ui-website(holdsmiddleware.ts,app/page.ts,package.json,tsconfig.json,README.md,AGENTS.md)LANDMINE: do not touch
packages/ui/packages/registry/packages/ui/packages/registry/is a DIFFERENT workspace that must stay. It holds the component sources thatwebsite/scripts/copy-registry.mjsmirrors intowebsite/components/ui/at build time, which the gallery detail pages (website/app/ui/[name]/page.ts) statically import. Deleting it 500s every component page in production, which is exactly regression #526. Thepackages/ui/packages/*workspace glob covers both, so only thewebsitesubdirectory goes.Where to edit
package.jsonL14, drop the"docs"workspace entry. The ui site rides thepackages/ui/packages/*glob (L12), so that glob stays as-is.package.jsonL33, drop the"ui:dev": "npm run dev --workspace=@webjsdev/ui-website"script. Check the surroundingdevandstartscripts for concurrently-style invocations referencing the docs or ui-website ports.package-lock.jsonwithnpm installafter the workspace removal. Do not hand-edit it.Dockerfile, remove L52 to L56 (COPY packages/ui/packages/website/package.json,COPY docs/package.json) and L70 (COPY docs ./docs). The build FAILS on a missing COPY source, so these must go in the same commit. L124 to L125 already carries a comment about both services; update it rather than leaving a comment describing deleted things.compose.yaml, remove thedocsservice (L33 to L36, port 15002) and theui-websiteservice (L71 to L74, port 15003). Update the header comment at L1 to L8, which says "four services"..github/workflows/ci.yml, fix L37 and L53. Both loops readfor app in examples/blog website docs packages/ui/packages/websiteand becomeexamples/blog website. Update the step names on L35 and L51 ("blog, website, docs host, ui host"). Also review the comments at L462 to L463, L493, and L502 to L509, several of which explain why the redirect hosts are or are not covered.Test surfaces
Delete these two, which test middleware that will not exist:
test/docs/docs-host-redirect.test.mjs(93 lines)test/ui/ui-host-redirect.test.mjs(135 lines)Then update the references in:
test/preload-subset.test.mjs(2 refs)test/e2e/form-submission-and-race.test.mjs(6 refs)test/e2e/nested-layout-partial-swap.test.mjs(6 refs)test/bun/app-boot.mjs(1 ref)scripts/run-bun-tests.js(1 ref)packages/server/test/check/check.test.js(1 ref)packages/server/test/dev/dev-handler.test.js(1 ref)test/repo-health/dockerfile-bakes-ui-registry.test.mjs, which guards dogfood: bake the ui-website registry into the deploy image (Bun serve 500s without it) #526 and must KEEP passing. It referencespackages/ui/packages/registry(staying), but check whether it also asserts on the website host's Dockerfile lines.State this coverage gap plainly in the PR body rather than papering over it: the two deleted tests asserted that the redirect hosts keep resolving. That behaviour now lives in Cloudflare and CI cannot see it. Do not invent a network test against the live zone to replace them, since a CI job that fails when Cloudflare has a bad minute is worse than the gap. Note the gap and move on.
Doc surfaces (all mandatory; this is a doc-sync task as much as a deletion)
AGENTS.mdL88 reads "Runwebjs doctortoo when you touched an in-repo app (examples/blog,website,docs,packages/ui/packages/website) ... over all four". It becomes two apps.AGENTS.mdL520, the CLI-reference paragraph naming "the redirect-onlydocs/andpackages/ui/packages/website/hosts".framework-dev.mdL3 and L9, both describing the four in-repo apps and the one-image deploy.framework-dev.mdL38, the Cloudflare cache-purge section, says all four hostnames are proxied in the one zone. That stays TRUE (the hostnames still exist as redirects), but re-read it for accuracy.README.mdL153 ("all four apps at once"), L163 (the ports table row forui.webjs.dev redirect), L173 ("Override ports when running all four"). Check for adocs.webjs.devtable row too.website/AGENTS.md(2 refs).claude/skills/webjs-start-work/SKILL.md(5 refs)Invariants to respect
git worktree add -b <prefix>/<slug> ../webjs-<slug> origin/main); never work in the primary checkout. Enforced by.claude/hooks/require-worktree-for-edits.sh.npm run worktree:linkinside the fresh worktree, NOT a hand-rolled rootnode_modulessymlink.packages/serverkeeps a nestedws@8that a root-only link resolves up tows@7, failing hundreds of assertions that never name ws.WebJscapitalized in prose and lowercase only as a code token.chore:orrefactor:), imperative, under 72 chars, no AI attribution.Verification
npm installthennpm testclean.node --test test/repo-health/clean (the dogfood: bake the ui-website registry into the deploy image (Bun serve 500s without it) #526 guard specifically).docker build -t webjs-test .npm run devstill boots the remaining apps without a missing-workspace error.Out of scope for this issue (owner-driven, in order, AFTER merge)
docsanduirecords currently CNAME to Railway and must becomeCNAME -> webjs.dev, proxied. The redirect rules fire before the origin fetch so they work regardless, but a CNAME to a deleted Railway host is fragile and can surface Error 1016 on any path that bypasses a rule.webjs(1d05ab75-b64e-4920-94ef-1ca7d04778fc):@webjsdev/docs35d994ce-2076-483a-8271-7b29b70122c7(domainc32a97f9-9ede-4737-b734-19ad6ba2f83c)@webjsdev/ui-website66a96b5e-9a00-4c58-9ddb-fb655b99d8e6(domain32c090bd-fd79-4777-9207-a36e92343b84)Acceptance criteria
docs/andpackages/ui/packages/website/are gone;packages/ui/packages/registry/is untouchedpackage.jsonworkspaces and scripts carry no reference to either;package-lock.jsonregenerated vianpm installDockerfilebuilds clean with no COPY pointing at a deleted pathcompose.yamlruns the two remaining apps with no dead service.github/workflows/ci.ymlloops overexamples/blog websiteonly, in both the check and doctor stepstest/docs/docs-host-redirect.test.mjsandtest/ui/ui-host-redirect.test.mjsare deleted; every other referencing test updated and passingtest/repo-health/dockerfile-bakes-ui-registry.test.mjsstill passes (the dogfood: bake the ui-website registry into the deploy image (Bun serve 500s without it) #526 guard)AGENTS.md,framework-dev.md,README.md,website/AGENTS.md, and.claude/skills/webjs-start-work/SKILL.mdno longer describe four in-repo appsnpm testclean;npm run devboots without a missing-workspace error