diff --git a/lib/folk-comment-pin.ts b/lib/folk-comment-pin.ts
index aa88390..10be6c6 100644
--- a/lib/folk-comment-pin.ts
+++ b/lib/folk-comment-pin.ts
@@ -4,6 +4,7 @@
*/
import * as Automerge from "@automerge/automerge";
+import { getModuleApiBase } from "../shared/url-helpers";
import type { CommunitySync } from "./community-sync";
import type {
CommentPinAnchor,
@@ -535,7 +536,7 @@ export class CommentPinManager {
if (pin.linkedNoteId) {
html += `
-
📝 ${this.#escapeHtml(pin.linkedNoteTitle || "Linked note")}
@@ -669,7 +670,7 @@ export class CommentPinManager {
if (this.#members) return this.#members;
try {
const sess = JSON.parse(localStorage.getItem("encryptid_session") || "{}");
- const res = await fetch(`/${this.#spaceSlug}/api/space-members`, {
+ const res = await fetch(`${getModuleApiBase("rspace")}/api/space-members`, {
headers: sess?.accessToken ? { Authorization: `Bearer ${sess.accessToken}` } : {},
});
if (!res.ok) return [];
@@ -685,7 +686,7 @@ export class CommentPinManager {
if (this.#notes) return this.#notes;
try {
const sess = JSON.parse(localStorage.getItem("encryptid_session") || "{}");
- const res = await fetch(`/${this.#spaceSlug}/rnotes/api/notes?limit=50`, {
+ const res = await fetch(`${getModuleApiBase("rnotes")}/api/notes?limit=50`, {
headers: sess?.accessToken ? { Authorization: `Bearer ${sess.accessToken}` } : {},
});
if (!res.ok) return [];
@@ -816,7 +817,7 @@ export class CommentPinManager {
try {
const sess = JSON.parse(localStorage.getItem("encryptid_session") || "{}");
- await fetch(`/${this.#spaceSlug}/api/comment-pins/notify-mention`, {
+ await fetch(`${getModuleApiBase("rspace")}/api/comment-pins/notify-mention`, {
method: "POST",
headers: {
"Content-Type": "application/json",
@@ -879,7 +880,7 @@ export class CommentPinManager {
};
if (email) body.notifyEmail = email;
- const res = await fetch(`/${this.#spaceSlug}/rschedule/api/reminders`, {
+ const res = await fetch(`${getModuleApiBase("rschedule")}/api/reminders`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(body),
diff --git a/lib/folk-commitment-pool.ts b/lib/folk-commitment-pool.ts
index 1796a9c..b4499cb 100644
--- a/lib/folk-commitment-pool.ts
+++ b/lib/folk-commitment-pool.ts
@@ -7,6 +7,7 @@
import { FolkShape } from "./folk-shape";
import { css, html } from "./tags";
+import { getModuleApiBase } from "../shared/url-helpers";
// ── Skill constants (mirrored from rtime/schemas to avoid server import) ──
@@ -299,7 +300,7 @@ export class FolkCommitmentPool extends FolkShape {
async #fetchCommitments() {
try {
- const resp = await fetch(`/${this.#spaceSlug}/rtime/api/commitments`);
+ const resp = await fetch(`${getModuleApiBase("rtime")}/api/commitments`);
if (!resp.ok) return;
const data = await resp.json();
const commitments: PoolCommitment[] = data.commitments || [];
diff --git a/lib/folk-feed.ts b/lib/folk-feed.ts
index 36dca8c..d7bbd83 100644
--- a/lib/folk-feed.ts
+++ b/lib/folk-feed.ts
@@ -20,6 +20,7 @@
import { FolkShape } from "./folk-shape";
import { FLOW_COLORS, FLOW_LABELS } from "./layer-types";
import type { FlowKind } from "./layer-types";
+import { getModuleApiBase, rspaceNavUrl, getCurrentSpace } from "../shared/url-helpers";
export class FolkFeed extends FolkShape {
static tagName = "folk-feed";
@@ -121,8 +122,7 @@ export class FolkFeed extends FolkShape {
this.#inner.querySelector(".feed-navigate")?.addEventListener("click", (e) => {
e.stopPropagation();
if (this.sourceModule) {
- const space = this.#getSpaceSlug();
- window.location.href = `/${space}/${this.sourceModule}`;
+ window.location.href = rspaceNavUrl(getCurrentSpace(), this.sourceModule);
}
});
@@ -150,9 +150,8 @@ export class FolkFeed extends FolkShape {
try {
// Construct feed URL based on feed ID
- const space = this.#getSpaceSlug();
const feedEndpoint = this.#getFeedEndpoint();
- const url = `/${space}/${this.sourceModule}/api/${feedEndpoint}`;
+ const url = `${getModuleApiBase(this.sourceModule)}/api/${feedEndpoint}`;
const res = await fetch(url);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
@@ -257,12 +256,6 @@ export class FolkFeed extends FolkShape {
return moduleEndpoints[this.feedId] || moduleEndpoints.default || this.feedId;
}
- #getSpaceSlug(): string {
- // Try to get from URL
- const parts = window.location.pathname.split("/").filter(Boolean);
- return parts[0] || "demo";
- }
-
// ── Render feed items ──
#renderItems() {
@@ -327,7 +320,6 @@ export class FolkFeed extends FolkShape {
/** Navigate to the source item in its module */
#navigateToItem(item: any) {
- const space = this.#getSpaceSlug();
const mod = this.sourceModule;
// Build a deep link to the item in its source module
@@ -338,7 +330,7 @@ export class FolkFeed extends FolkShape {
sourceModule: mod,
itemId: item.id,
item,
- url: `/${space}/${mod}`,
+ url: getModuleApiBase(mod),
}
}));
}
@@ -427,9 +419,8 @@ export class FolkFeed extends FolkShape {
// Write back to source module API
try {
- const space = this.#getSpaceSlug();
const endpoint = this.#getWriteBackEndpoint(item);
- const url = `/${space}/${this.sourceModule}/api/${endpoint}`;
+ const url = `${getModuleApiBase(this.sourceModule)}/api/${endpoint}`;
const method = this.#getWriteBackMethod();
const token = this.#getAuthToken();
diff --git a/lib/folk-map.ts b/lib/folk-map.ts
index 2bc5011..1f49999 100644
--- a/lib/folk-map.ts
+++ b/lib/folk-map.ts
@@ -1,5 +1,6 @@
import { FolkShape } from "./folk-shape";
import { css, html } from "./tags";
+import { getModuleApiBase } from "../shared/url-helpers";
import type {
RoomState,
ParticipantState,
@@ -942,9 +943,7 @@ export class FolkMap extends FolkShape {
}
#getApiBase(): string {
- const match = window.location.pathname.match(/^\/([^/]+)/);
- const spaceSlug = match ? match[1] : "default";
- return `/${spaceSlug}/rmaps`;
+ return getModuleApiBase("rmaps");
}
async #initRoomSync() {
diff --git a/lib/folk-multisig-email.ts b/lib/folk-multisig-email.ts
index f5f84bb..01ce205 100644
--- a/lib/folk-multisig-email.ts
+++ b/lib/folk-multisig-email.ts
@@ -1,5 +1,6 @@
import { FolkShape } from "./folk-shape";
import { css, html } from "./tags";
+import { getModuleApiBase } from "../shared/url-helpers";
const styles = css`
:host {
@@ -295,8 +296,7 @@ export class FolkMultisigEmail extends FolkShape {
}
private getApiBase(): string {
- const space = (this as any).spaceSlug || (window as any).__communitySync?.communitySlug || "demo";
- return `/${space}/rinbox`;
+ return getModuleApiBase("rinbox");
}
private getAuthHeaders(): Record
{
diff --git a/lib/folk-social-campaign.ts b/lib/folk-social-campaign.ts
index da61643..c7ff7e5 100644
--- a/lib/folk-social-campaign.ts
+++ b/lib/folk-social-campaign.ts
@@ -1,5 +1,6 @@
import { FolkShape } from "./folk-shape";
import { css, html } from "./tags";
+import { getModuleApiBase } from "../shared/url-helpers";
const PLATFORM_ICONS: Record = {
x: "𝕏", linkedin: "in", instagram: "📷", youtube: "▶",
@@ -331,7 +332,7 @@ export class FolkSocialCampaign extends FolkShape {
e.stopPropagation();
this.dispatchEvent(new CustomEvent("navigate-to-module", {
bubbles: true, composed: true,
- detail: { path: `/${this.#spaceSlug}/rsocials/campaigns?id=${this.#campaignId}` },
+ detail: { path: `${getModuleApiBase("rsocials")}/campaigns?id=${this.#campaignId}` },
}));
});
diff --git a/lib/folk-social-thread.ts b/lib/folk-social-thread.ts
index 3289310..14d302a 100644
--- a/lib/folk-social-thread.ts
+++ b/lib/folk-social-thread.ts
@@ -1,6 +1,7 @@
import { FolkShape } from "./folk-shape";
import { css, html } from "./tags";
import type { SocialPlatform } from "./folk-social-post";
+import { getModuleApiBase } from "../shared/url-helpers";
const PLATFORM_COLORS: Record = {
x: "#000000",
@@ -331,7 +332,7 @@ export class FolkSocialThread extends FolkShape {
this.dispatchEvent(new CustomEvent("navigate-to-module", {
bubbles: true,
composed: true,
- detail: { path: `/${this.#spaceSlug}/rsocials/thread-editor?id=${this.#threadId}` },
+ detail: { path: `${getModuleApiBase("rsocials")}/thread-editor?id=${this.#threadId}` },
}));
});
diff --git a/lib/folk-spider-3d.ts b/lib/folk-spider-3d.ts
index 36343d1..548a7db 100644
--- a/lib/folk-spider-3d.ts
+++ b/lib/folk-spider-3d.ts
@@ -7,6 +7,7 @@
import { FolkShape } from "./folk-shape";
import { css, html } from "./tags";
+import { getModuleApiBase } from "../shared/url-helpers";
import {
computeSpider3D,
computeRadarPolygon,
@@ -488,7 +489,7 @@ export class FolkSpider3D extends FolkShape {
try {
const token = localStorage.getItem("rspace-token") || "";
- const res = await fetch(`/${this.#space}/connections`, {
+ const res = await fetch(`${getModuleApiBase("rspace")}/connections`, {
headers: token ? { Authorization: `Bearer ${token}` } : {},
});
if (!res.ok) throw new Error(`HTTP ${res.status}`);
diff --git a/lib/folk-splat.ts b/lib/folk-splat.ts
index 2972bfe..6f1f4a6 100644
--- a/lib/folk-splat.ts
+++ b/lib/folk-splat.ts
@@ -1,5 +1,6 @@
import { FolkShape } from "./folk-shape";
import { css, html } from "./tags";
+import { getModuleApiBase } from "../shared/url-helpers";
const styles = css`
:host {
@@ -327,8 +328,7 @@ export class FolkSplat extends FolkShape {
async #loadGallery(container: HTMLElement, viewerArea: HTMLElement) {
container.innerHTML = '';
try {
- const spaceSlug = this.#getSpaceSlug();
- const res = await fetch(`/${spaceSlug}/rsplat/api/splats?limit=20`);
+ const res = await fetch(`${getModuleApiBase("rsplat")}/api/splats?limit=20`);
if (!res.ok) throw new Error("Failed to load splats");
const data = await res.json();
this.#gallerySplats = data.splats || [];
@@ -351,8 +351,7 @@ export class FolkSplat extends FolkShape {
const slug = (item as HTMLElement).dataset.slug;
const splat = this.#gallerySplats.find((s) => s.slug === slug);
if (splat) {
- const spaceSlug = this.#getSpaceSlug();
- const url = `/${spaceSlug}/rsplat/api/splats/${splat.slug}/${splat.slug}.${splat.file_format}`;
+ const url = `${getModuleApiBase("rsplat")}/api/splats/${splat.slug}/${splat.slug}.${splat.file_format}`;
if (this.#urlInput) this.#urlInput.value = url;
container.style.display = "none";
this.#loadSplat(url, viewerArea);
@@ -410,19 +409,13 @@ export class FolkSplat extends FolkShape {
} catch (err) {
// Fallback: show as iframe pointing to splat viewer page
console.warn("[folk-splat] Three.js not available, using iframe fallback");
- const spaceSlug = this.#getSpaceSlug();
const slug = url.split("/").filter(Boolean).pop()?.split(".")[0] || "";
- viewerArea.innerHTML = ``;
+ viewerArea.innerHTML = ``;
} finally {
this.#isLoading = false;
}
}
- #getSpaceSlug(): string {
- const pathParts = window.location.pathname.split("/").filter(Boolean);
- return pathParts[0] || "demo";
- }
-
#escapeHtml(text: string): string {
const div = document.createElement("div");
div.textContent = text;
diff --git a/lib/folk-task-request.ts b/lib/folk-task-request.ts
index a50e347..43e12db 100644
--- a/lib/folk-task-request.ts
+++ b/lib/folk-task-request.ts
@@ -7,6 +7,7 @@
import { FolkShape } from "./folk-shape";
import { css, html } from "./tags";
+import { getModuleApiBase } from "../shared/url-helpers";
// Skill constants (mirrored from rtime/schemas)
const SKILL_COLORS: Record = {
@@ -404,7 +405,7 @@ export class FolkTaskRequest extends FolkShape {
// Get auth token from cookie or localStorage
const token = document.cookie.split(";").map(c => c.trim()).find(c => c.startsWith("auth_token="))?.split("=")[1]
|| localStorage.getItem("auth_token") || "";
- await fetch(`/${this.#spaceSlug}/rtime/api/connections`, {
+ await fetch(`${getModuleApiBase("rtime")}/api/connections`, {
method: "POST",
headers: {
"Content-Type": "application/json",
diff --git a/lib/folk-transaction-builder.ts b/lib/folk-transaction-builder.ts
index 59983d3..c2d4186 100644
--- a/lib/folk-transaction-builder.ts
+++ b/lib/folk-transaction-builder.ts
@@ -6,6 +6,7 @@
import { FolkShape } from "./folk-shape";
import { css, html } from "./tags";
+import { getModuleApiBase } from "../shared/url-helpers";
const styles = css`
:host {
@@ -283,8 +284,7 @@ export class FolkTransactionBuilder extends FolkShape {
}
#apiBase(): string {
- const space = this.#getSpaceSlug();
- return `/${space}/rwallet/api/safe/${this.#chainId}/${this.#safeAddress}`;
+ return `${getModuleApiBase("rwallet")}/api/safe/${this.#chainId}/${this.#safeAddress}`;
}
async #apiFetch(path: string, opts?: RequestInit): Promise {
diff --git a/modules/crowdsurf/components/folk-crowdsurf-dashboard.ts b/modules/crowdsurf/components/folk-crowdsurf-dashboard.ts
index bd16928..b3b5b6b 100644
--- a/modules/crowdsurf/components/folk-crowdsurf-dashboard.ts
+++ b/modules/crowdsurf/components/folk-crowdsurf-dashboard.ts
@@ -11,6 +11,7 @@ import { startPresenceHeartbeat } from '../../../shared/collab-presence';
import { CrowdSurfLocalFirstClient } from '../local-first-client';
import type { CrowdSurfDoc, CrowdSurfPrompt, Contribution } from '../schemas';
import { getDecayProgress, getTimeRemaining, getRightSwipeCount, isReadyToTrigger, getUrgency, parseContributions } from '../schemas';
+import { getModuleApiBase } from "../../../shared/url-helpers";
// ── Auth helpers ──
function getSession(): { accessToken: string; claims: { sub: string; did?: string; username?: string } } | null {
@@ -624,7 +625,7 @@ class FolkCrowdSurfDashboard extends HTMLElement {
this.rankLoading = true;
this.render();
this.bindEvents();
- fetch(`/${this.space}/crowdsurf/api/crowdsurf/pair?space=${this.space}`)
+ fetch(`${getModuleApiBase("crowdsurf")}/api/crowdsurf/pair?space=${this.space}`)
.then(r => r.json())
.then(data => {
if (data.a && data.b) {
@@ -697,7 +698,7 @@ class FolkCrowdSurfDashboard extends HTMLElement {
}
// Live mode: POST to API
- fetch(`/${this.space}/crowdsurf/api/crowdsurf/compare?space=${this.space}`, {
+ fetch(`${getModuleApiBase("crowdsurf")}/api/crowdsurf/compare?space=${this.space}`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ winnerId, loserId }),
diff --git a/modules/rbnb/components/folk-bnb-view.ts b/modules/rbnb/components/folk-bnb-view.ts
index c74e427..87d2709 100644
--- a/modules/rbnb/components/folk-bnb-view.ts
+++ b/modules/rbnb/components/folk-bnb-view.ts
@@ -10,6 +10,7 @@ import type { TourStep } from '../../../shared/tour-engine';
import './folk-listing';
import './folk-stay-request';
import { startPresenceHeartbeat } from '../../../shared/collab-presence';
+import { getModuleApiBase } from "../../../shared/url-helpers";
const BNB_TOUR_STEPS: TourStep[] = [
{ target: '.bnb-search', title: 'Search', message: 'Filter listings by location, type, or economy model.' },
@@ -89,9 +90,9 @@ class FolkBnbView extends HTMLElement {
async #loadData() {
try {
const [listingsRes, staysRes, statsRes] = await Promise.all([
- fetch(`/${this.#space}/rbnb/api/listings`),
- fetch(`/${this.#space}/rbnb/api/stays`),
- fetch(`/${this.#space}/rbnb/api/stats`),
+ fetch(`${getModuleApiBase("rbnb")}/api/listings`),
+ fetch(`${getModuleApiBase("rbnb")}/api/stays`),
+ fetch(`${getModuleApiBase("rbnb")}/api/stats`),
]);
if (listingsRes.ok) {
@@ -414,7 +415,7 @@ class FolkBnbView extends HTMLElement {
async #handleStayAction(stayId: string, action: string) {
try {
- const res = await fetch(`/${this.#space}/rbnb/api/stays/${stayId}/${action}`, {
+ const res = await fetch(`${getModuleApiBase("rbnb")}/api/stays/${stayId}/${action}`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
});
@@ -430,7 +431,7 @@ class FolkBnbView extends HTMLElement {
async #handleStayMessage(stayId: string, body: string) {
try {
- const res = await fetch(`/${this.#space}/rbnb/api/stays/${stayId}/messages`, {
+ const res = await fetch(`${getModuleApiBase("rbnb")}/api/stays/${stayId}/messages`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ body, sender_name: 'You' }),
diff --git a/modules/rbnb/components/folk-listing.ts b/modules/rbnb/components/folk-listing.ts
index 374119a..8816574 100644
--- a/modules/rbnb/components/folk-listing.ts
+++ b/modules/rbnb/components/folk-listing.ts
@@ -5,6 +5,8 @@
* capacity, location, economy badge, availability dot, endorsement count.
*/
+import { getModuleApiBase } from "../../../shared/url-helpers";
+
const ECONOMY_COLORS: Record = {
gift: { bg: 'rgba(52,211,153,0.12)', fg: '#34d399', label: 'Gift', icon: '\u{1F49A}' },
exchange: { bg: 'rgba(96,165,250,0.12)', fg: '#60a5fa', label: 'Exchange', icon: '\u{1F91D}' },
@@ -53,7 +55,7 @@ class FolkListing extends HTMLElement {
if (!listingId) return;
try {
- const res = await fetch(`/${space}/rbnb/api/listings/${listingId}`);
+ const res = await fetch(`${getModuleApiBase("rbnb")}/api/listings/${listingId}`);
if (res.ok) {
this.#data = await res.json();
this.#render();
diff --git a/modules/rbnb/components/folk-stay-request.ts b/modules/rbnb/components/folk-stay-request.ts
index d3f6d60..147b018 100644
--- a/modules/rbnb/components/folk-stay-request.ts
+++ b/modules/rbnb/components/folk-stay-request.ts
@@ -5,6 +5,8 @@
* action buttons (accept/decline/cancel/complete), endorsement prompt.
*/
+import { getModuleApiBase } from "../../../shared/url-helpers";
+
const STATUS_STYLES: Record = {
pending: { bg: 'rgba(245,158,11,0.15)', fg: '#f59e0b', label: 'Pending' },
accepted: { bg: 'rgba(52,211,153,0.15)', fg: '#34d399', label: 'Accepted' },
@@ -50,7 +52,7 @@ class FolkStayRequest extends HTMLElement {
if (!stayId) return;
try {
- const res = await fetch(`/${space}/rbnb/api/stays/${stayId}`);
+ const res = await fetch(`${getModuleApiBase("rbnb")}/api/stays/${stayId}`);
if (res.ok) {
this.#data = await res.json();
this.#render();
diff --git a/modules/rbooks/mod.ts b/modules/rbooks/mod.ts
index 83537fc..f322d8a 100644
--- a/modules/rbooks/mod.ts
+++ b/modules/rbooks/mod.ts
@@ -347,7 +347,7 @@ routes.get("/read/:id", async (c) => {
});
// Build the PDF URL relative to this module's mount point
- const pdfUrl = `/${spaceSlug}/rbooks/api/books/${book.slug}/pdf`;
+ const pdfUrl = c.get("isSubdomain") ? `/rbooks/api/books/${book.slug}/pdf` : `/${spaceSlug}/rbooks/api/books/${book.slug}/pdf`;
const html = renderShell({
title: `${book.title} | rSpace`,
diff --git a/modules/rcart/components/folk-cart-shop.ts b/modules/rcart/components/folk-cart-shop.ts
index 84226b8..0f84487 100644
--- a/modules/rcart/components/folk-cart-shop.ts
+++ b/modules/rcart/components/folk-cart-shop.ts
@@ -633,7 +633,7 @@ class FolkCartShop extends HTMLElement {
this.shadow.querySelectorAll("[data-action='copy-pay-url']").forEach((el) => {
el.addEventListener("click", () => {
const payId = (el as HTMLElement).dataset.payId;
- const url = `${window.location.origin}/${this.space}/rcart/pay/${payId}`;
+ const url = `${window.location.origin}${this.getApiBase()}/pay/${payId}`;
navigator.clipboard.writeText(url);
(el as HTMLElement).textContent = 'Copied!';
setTimeout(() => { (el as HTMLElement).textContent = 'Copy Link'; }, 2000);
@@ -644,7 +644,7 @@ class FolkCartShop extends HTMLElement {
this.shadow.querySelectorAll("[data-group-buy-id]").forEach((el) => {
el.addEventListener("click", () => {
const buyId = (el as HTMLElement).dataset.groupBuyId!;
- const url = `/${this.space}/rcart/buy/${buyId}`;
+ const url = `${this.getApiBase()}/buy/${buyId}`;
window.location.href = url;
});
});
@@ -1116,7 +1116,7 @@ class FolkCartShop extends HTMLElement {
if (this.groupBuys.length === 0) {
return ``;
}
@@ -1333,7 +1333,7 @@ class FolkCartShop extends HTMLElement {
${new Date(pay.created_at).toLocaleDateString()}
${pay.status === 'pending' ? `
` : ''}
diff --git a/modules/rcart/components/folk-payment-page.ts b/modules/rcart/components/folk-payment-page.ts
index 2ffc4ff..72b6b55 100644
--- a/modules/rcart/components/folk-payment-page.ts
+++ b/modules/rcart/components/folk-payment-page.ts
@@ -66,7 +66,7 @@ class FolkPaymentPage extends HTMLElement {
disconnectedCallback() {
this.stopPolling();
this.walletDiscovery?.stop?.();
- window.removeEventListener('message', this.handleTransakMessage);
+ window.removeEventListener('message', this.handlePaymentMessage);
}
private getApiBase(): string {
@@ -116,7 +116,7 @@ class FolkPaymentPage extends HTMLElement {
private async generateQR() {
try {
const QRCode = await import('qrcode');
- const payUrl = `${window.location.origin}/${this.space}/rcart/pay/${this.paymentId}`;
+ const payUrl = `${window.location.origin}${this.getApiBase()}/pay/${this.paymentId}`;
this.qrDataUrl = await QRCode.toDataURL(payUrl, { margin: 2, width: 200 });
} catch { /* QR generation optional */ }
}
@@ -528,7 +528,7 @@ class FolkPaymentPage extends HTMLElement {
const explorer = explorerBase[p.chainId] || '';
const cartLink = p.linkedCartId
- ? ``
+ ? ``
: '';
return `
diff --git a/modules/rcart/components/folk-payment-request.ts b/modules/rcart/components/folk-payment-request.ts
index d519209..9a699ff 100644
--- a/modules/rcart/components/folk-payment-request.ts
+++ b/modules/rcart/components/folk-payment-request.ts
@@ -155,8 +155,8 @@ class FolkPaymentRequest extends HTMLElement {
// Build URLs
const host = window.location.origin;
- this.payUrl = `${host}/${this.space}/rcart/pay/${paymentId}`;
- this.qrSvgUrl = `${host}/${this.space}/rcart/api/payments/${paymentId}/qr`;
+ this.payUrl = `${host}${this.getApiBase()}/pay/${paymentId}`;
+ this.qrSvgUrl = `${host}${this.getApiBase()}/api/payments/${paymentId}/qr`;
// Generate client-side QR
try {
@@ -296,8 +296,8 @@ class FolkPaymentRequest extends HTMLElement {
// Build URLs
const host = window.location.origin;
- this.payUrl = `${host}/${this.space}/rcart/pay/${this.generatedPayment.id}`;
- this.qrSvgUrl = `${host}/${this.space}/rcart/api/payments/${this.generatedPayment.id}/qr`;
+ this.payUrl = `${host}${this.getApiBase()}/pay/${this.generatedPayment.id}`;
+ this.qrSvgUrl = `${host}${this.getApiBase()}/api/payments/${this.generatedPayment.id}/qr`;
// Generate client-side QR
try {
diff --git a/modules/rchoices/components/folk-choices-dashboard.ts b/modules/rchoices/components/folk-choices-dashboard.ts
index 29db049..b28663e 100644
--- a/modules/rchoices/components/folk-choices-dashboard.ts
+++ b/modules/rchoices/components/folk-choices-dashboard.ts
@@ -9,6 +9,7 @@ import { TourEngine } from "../../../shared/tour-engine";
import { ChoicesLocalFirstClient } from "../local-first-client";
import type { ChoicesDoc, ChoiceSession, ChoiceVote } from "../schemas";
import { startPresenceHeartbeat } from '../../../shared/collab-presence';
+import { getModuleApiBase, rspaceNavUrl, getCurrentSpace } from "../../../shared/url-helpers";
// ── CrowdSurf types ──
interface CrowdSurfOption {
@@ -298,7 +299,7 @@ class FolkChoicesDashboard extends HTMLElement {
${isLive ? `LIVE` : ''}
@@ -472,14 +473,14 @@ class FolkChoicesDashboard extends HTMLElement {
return `
☑
No choices in this space yet.
-
Open the canvas and use the Poll, Rank, or Spider buttons to create one.
+
Open the canvas and use the Poll, Rank, or Spider buttons to create one.
`;
}
private renderGrid(icons: Record