fix: canonicalize space URLs to subdomain pattern
rspace.online/{space}/{moduleId} now 301-redirects to
{space}.rspace.online/{moduleId} — spaces are subdomains,
not path segments. e.g. rspace.online/demo/rnotes →
demo.rspace.online/rnotes.
Landing pages (rspace.online/{moduleId}) unchanged.
API sub-path rewrite for demo "Try Demo" unchanged.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
eee9cbed69
commit
9f3c9abf5b
|
|
@ -1124,15 +1124,17 @@ const server = Bun.serve<WSData>({
|
||||||
return app.fetch(rewrittenReq);
|
return app.fetch(rewrittenReq);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Bare-domain module routes: rspace.online/{moduleId}[/...] ──
|
// ── Bare-domain routing: rspace.online/{...} ──
|
||||||
// Exact module path → landing page; sub-paths rewrite to /demo/...
|
|
||||||
if (!subdomain && hostClean.includes("rspace.online")) {
|
if (!subdomain && hostClean.includes("rspace.online")) {
|
||||||
const pathSegments = url.pathname.split("/").filter(Boolean);
|
const pathSegments = url.pathname.split("/").filter(Boolean);
|
||||||
if (pathSegments.length >= 1) {
|
if (pathSegments.length >= 1) {
|
||||||
const firstSegment = pathSegments[0];
|
const firstSegment = pathSegments[0];
|
||||||
const allModules = getAllModules();
|
const allModules = getAllModules();
|
||||||
|
const knownModuleIds = new Set(allModules.map((m) => m.id));
|
||||||
const mod = allModules.find((m) => m.id === firstSegment);
|
const mod = allModules.find((m) => m.id === firstSegment);
|
||||||
|
|
||||||
if (mod) {
|
if (mod) {
|
||||||
|
// rspace.online/{moduleId} → landing page
|
||||||
if (pathSegments.length === 1) {
|
if (pathSegments.length === 1) {
|
||||||
// 1. Check for inline rich landing page
|
// 1. Check for inline rich landing page
|
||||||
if (mod.landingPage) {
|
if (mod.landingPage) {
|
||||||
|
|
@ -1157,12 +1159,23 @@ const server = Bun.serve<WSData>({
|
||||||
});
|
});
|
||||||
return new Response(html, { headers: { "Content-Type": "text/html" } });
|
return new Response(html, { headers: { "Content-Type": "text/html" } });
|
||||||
}
|
}
|
||||||
// Sub-paths → rewrite to /demo/{moduleId}/...
|
// rspace.online/{moduleId}/sub-path → rewrite to demo space internally
|
||||||
const rewrittenPath = `/demo${url.pathname}`;
|
const rewrittenPath = `/demo${url.pathname}`;
|
||||||
const rewrittenUrl = new URL(rewrittenPath + url.search, `http://localhost:${PORT}`);
|
const rewrittenUrl = new URL(rewrittenPath + url.search, `http://localhost:${PORT}`);
|
||||||
const rewrittenReq = new Request(rewrittenUrl, req);
|
const rewrittenReq = new Request(rewrittenUrl, req);
|
||||||
return app.fetch(rewrittenReq);
|
return app.fetch(rewrittenReq);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// rspace.online/{space}/{...} → redirect to {space}.rspace.online/{...}
|
||||||
|
// (space is not a module ID — it's a space slug, canonicalize to subdomain)
|
||||||
|
if (!knownModuleIds.has(firstSegment) && pathSegments.length >= 2) {
|
||||||
|
const space = firstSegment;
|
||||||
|
const rest = "/" + pathSegments.slice(1).join("/");
|
||||||
|
const baseDomain = hostClean.replace(/^www\./, "");
|
||||||
|
return Response.redirect(
|
||||||
|
`${url.protocol}//${space}.${baseDomain}${rest}${url.search}`, 301
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue