fix(rsocials): subdomain-aware link generation
Links on subdomain routing (e.g. jeff.rspace.online) were including the space in the path (/demo/rsocials/campaigns) instead of just /rsocials/campaigns. Added basePath getter to all components and detect subdomain in the server-rendered hub page. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
eedf2cf189
commit
a5c7bb784e
|
|
@ -72,6 +72,14 @@ export class FolkCampaignManager extends HTMLElement {
|
|||
});
|
||||
}
|
||||
|
||||
private get basePath() {
|
||||
const host = window.location.hostname;
|
||||
if (host.endsWith('.rspace.online') || host.endsWith('.rsocials.online')) {
|
||||
return '/rsocials/';
|
||||
}
|
||||
return `/${this._space}/rsocials/`;
|
||||
}
|
||||
|
||||
private esc(s: string): string {
|
||||
return s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
|
||||
}
|
||||
|
|
@ -131,7 +139,7 @@ export class FolkCampaignManager extends HTMLElement {
|
|||
</div>
|
||||
</div>
|
||||
<div class="actions">
|
||||
<a href="/rsocials/thread-editor" class="btn btn--outline">Open Thread Editor</a>
|
||||
<a href="${this.basePath}thread-editor" class="btn btn--outline">Open Thread Editor</a>
|
||||
<button class="btn btn--primary" id="import-md-btn">Import from Markdown</button>
|
||||
</div>
|
||||
${phaseHTML}
|
||||
|
|
|
|||
|
|
@ -121,6 +121,14 @@ class FolkCampaignPlanner extends HTMLElement {
|
|||
private shadow: ShadowRoot;
|
||||
private space = '';
|
||||
|
||||
private get basePath() {
|
||||
const host = window.location.hostname;
|
||||
if (host.endsWith('.rspace.online') || host.endsWith('.rsocials.online')) {
|
||||
return '/rsocials/';
|
||||
}
|
||||
return `/${this.space}/rsocials/`;
|
||||
}
|
||||
|
||||
// Data
|
||||
private nodes: CampaignPlannerNode[] = [];
|
||||
private edges: CampaignEdge[] = [];
|
||||
|
|
@ -820,7 +828,7 @@ class FolkCampaignPlanner extends HTMLElement {
|
|||
} else if (action === 'open-thread') {
|
||||
const d = node.data as ThreadNodeData;
|
||||
if (d.threadId) {
|
||||
window.location.href = `/rsocials/thread-editor/${d.threadId}/edit`;
|
||||
window.location.href = `${this.basePath}thread-editor/${d.threadId}/edit`;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
@ -1457,7 +1465,7 @@ class FolkCampaignPlanner extends HTMLElement {
|
|||
if (node?.type === 'thread') {
|
||||
const d = node.data as ThreadNodeData;
|
||||
if (d.threadId) {
|
||||
window.location.href = `/rsocials/thread-editor/${d.threadId}/edit`;
|
||||
window.location.href = `${this.basePath}thread-editor/${d.threadId}/edit`;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -274,7 +274,7 @@ export class FolkThreadBuilder extends HTMLElement {
|
|||
</div>
|
||||
<div class="preview ro-cards">${tweetCards}</div>
|
||||
<div class="ro-actions">
|
||||
<a href="/rsocials/thread-editor/${this.esc(t.id)}/edit" class="btn btn--primary">Edit Thread</a>
|
||||
<a href="${this.basePath}thread-editor/${this.esc(t.id)}/edit" class="btn btn--primary">Edit Thread</a>
|
||||
<button class="btn btn--outline" id="ro-copy-thread">Copy Thread</button>
|
||||
<button class="btn btn--outline" id="ro-copy-link">Copy Link</button>
|
||||
<div class="export-dropdown">
|
||||
|
|
@ -289,8 +289,8 @@ export class FolkThreadBuilder extends HTMLElement {
|
|||
</div>
|
||||
</div>
|
||||
<div class="ro-cta">
|
||||
<a href="/rsocials/thread-editor" class="btn btn--success">Create Your Own Thread</a>
|
||||
<a href="/rsocials/threads" class="btn btn--outline">Browse All Threads</a>
|
||||
<a href="${this.basePath}thread-editor" class="btn btn--success">Create Your Own Thread</a>
|
||||
<a href="${this.basePath}threads" class="btn btn--outline">Browse All Threads</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="toast" id="export-toast" hidden></div>
|
||||
|
|
|
|||
|
|
@ -82,6 +82,14 @@ export class FolkThreadGallery extends HTMLElement {
|
|||
this.render();
|
||||
}
|
||||
|
||||
private get basePath() {
|
||||
const host = window.location.hostname;
|
||||
if (host.endsWith('.rspace.online') || host.endsWith('.rsocials.online')) {
|
||||
return '/rsocials/';
|
||||
}
|
||||
return `/${this._space}/rsocials/`;
|
||||
}
|
||||
|
||||
private esc(s: string): string {
|
||||
return s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
|
||||
}
|
||||
|
|
@ -94,7 +102,7 @@ export class FolkThreadGallery extends HTMLElement {
|
|||
const cardsHTML = threads.length === 0
|
||||
? `<div class="empty">
|
||||
<p>No threads yet. Create your first thread!</p>
|
||||
<a href="/rsocials/thread-editor" class="btn btn--success">Create Thread</a>
|
||||
<a href="${this.basePath}thread-editor" class="btn btn--success">Create Thread</a>
|
||||
</div>`
|
||||
: `<div class="grid">
|
||||
${threads.map(t => {
|
||||
|
|
@ -105,8 +113,8 @@ export class FolkThreadGallery extends HTMLElement {
|
|||
? `<div class="card__image"><img src="${this.esc(t.imageUrl)}" alt="" loading="lazy"></div>`
|
||||
: '';
|
||||
const href = this._isDemoFallback
|
||||
? `/rsocials/thread-editor`
|
||||
: `/rsocials/thread-editor/${this.esc(t.id)}/edit`;
|
||||
? `${this.basePath}thread-editor`
|
||||
: `${this.basePath}thread-editor/${this.esc(t.id)}/edit`;
|
||||
return `<a href="${href}" class="card">
|
||||
${imageTag}
|
||||
<h3 class="card__title">${this.esc(t.title || 'Untitled Thread')}</h3>
|
||||
|
|
@ -165,7 +173,7 @@ export class FolkThreadGallery extends HTMLElement {
|
|||
<div class="gallery">
|
||||
<div class="header">
|
||||
<h1>Threads</h1>
|
||||
<a href="/rsocials/thread-editor" class="btn btn--primary">New Thread</a>
|
||||
<a href="${this.basePath}thread-editor" class="btn btn--primary">New Thread</a>
|
||||
</div>
|
||||
${cardsHTML}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -644,7 +644,9 @@ routes.get("/landing", (c) => {
|
|||
|
||||
routes.get("/", (c) => {
|
||||
const space = c.req.param("space") || "demo";
|
||||
const base = `/${escapeHtml(space)}/rsocials`;
|
||||
const host = c.req.header("host")?.split(":")[0] || "";
|
||||
const isSubdomain = (host.endsWith(".rspace.online") && host !== "rspace.online" && !host.startsWith("www.")) || host.endsWith(".rsocials.online");
|
||||
const base = isSubdomain ? "/rsocials" : `/${escapeHtml(space)}/rsocials`;
|
||||
return c.html(renderShell({
|
||||
title: `rSocials — ${space} | rSpace`,
|
||||
moduleId: "rsocials",
|
||||
|
|
|
|||
Loading…
Reference in New Issue