diff --git a/server/index.ts b/server/index.ts index d35c4a5..18077a9 100644 --- a/server/index.ts +++ b/server/index.ts @@ -64,7 +64,7 @@ import { splatModule } from "../modules/splat/mod"; import { photosModule } from "../modules/photos/mod"; import { rsocialsModule } from "../modules/rsocials/mod"; import { spaces } from "./spaces"; -import { renderShell } from "./shell"; +import { renderShell, renderModuleLanding } from "./shell"; import { syncServer } from "./sync-instance"; import { loadAllDocs } from "./local-first/doc-persistence"; @@ -781,14 +781,23 @@ const server = Bun.serve({ } // ── Bare-domain module routes: rspace.online/{moduleId}[/...] ── - // Rewrite to /demo/{moduleId}/... so the normal shell renders identically - // to how standalone domains (e.g. rtube.online) serve their content. + // Exact module path → landing page; sub-paths rewrite to /demo/... if (!subdomain && hostClean.includes("rspace.online")) { const pathSegments = url.pathname.split("/").filter(Boolean); if (pathSegments.length >= 1) { const firstSegment = pathSegments[0]; - const knownModuleIds = new Set(getAllModules().map((m) => m.id)); - if (knownModuleIds.has(firstSegment)) { + const allModules = getAllModules(); + const mod = allModules.find((m) => m.id === firstSegment); + if (mod) { + if (pathSegments.length === 1) { + // Exact module path → show landing page + const html = renderModuleLanding({ + module: mod, + modules: getModuleInfoList(), + }); + return new Response(html, { headers: { "Content-Type": "text/html" } }); + } + // Sub-paths → rewrite to /demo/{moduleId}/... const rewrittenPath = `/demo${url.pathname}`; const rewrittenUrl = new URL(rewrittenPath + url.search, `http://localhost:${PORT}`); const rewrittenReq = new Request(rewrittenUrl, req); diff --git a/server/shell.ts b/server/shell.ts index 3682a28..18fd33f 100644 --- a/server/shell.ts +++ b/server/shell.ts @@ -425,61 +425,6 @@ export interface ModuleLandingOptions { export function renderModuleLanding(opts: ModuleLandingOptions): string { const { module: mod, modules, theme = "dark" } = opts; const moduleListJSON = JSON.stringify(modules); - - // Modules with a standalone domain: embed it in a full-page iframe - if (mod.standaloneDomain) { - const embedUrl = `https://${escapeAttr(mod.standaloneDomain)}`; - return ` - - - - - - ${escapeHtml(mod.name)} — rSpace - - - - - - -
-
- -
-
- -
-
- -
- - -`; - } - - // Modules without a standalone domain: simple generated landing page const demoUrl = `https://demo.rspace.online/${mod.id}`; return `