diff --git a/apps/dotcom-worker/src/lib/TLDrawDurableObject.ts b/apps/dotcom-worker/src/lib/TLDrawDurableObject.ts
index 4746320dc..af2dfd5e0 100644
--- a/apps/dotcom-worker/src/lib/TLDrawDurableObject.ts
+++ b/apps/dotcom-worker/src/lib/TLDrawDurableObject.ts
@@ -2,7 +2,13 @@
///
import { SupabaseClient } from '@supabase/supabase-js'
-import { ROOM_OPEN_MODE, type RoomOpenMode } from '@tldraw/dotcom-shared'
+import {
+ READ_ONLY_LEGACY_PREFIX,
+ READ_ONLY_PREFIX,
+ ROOM_OPEN_MODE,
+ ROOM_PREFIX,
+ type RoomOpenMode,
+} from '@tldraw/dotcom-shared'
import {
DBLoadResultType,
RoomSnapshot,
@@ -91,22 +97,22 @@ export class TLDrawDurableObject extends TLServer {
readonly router = Router()
.get(
- '/r/:roomId',
+ `/${ROOM_PREFIX}/:roomId`,
(req) => this.extractDocumentInfoFromRequest(req, ROOM_OPEN_MODE.READ_WRITE),
(req) => this.onRequest(req)
)
.get(
- '/v/:roomId',
+ `/${READ_ONLY_LEGACY_PREFIX}/:roomId`,
(req) => this.extractDocumentInfoFromRequest(req, ROOM_OPEN_MODE.READ_ONLY_LEGACY),
(req) => this.onRequest(req)
)
.get(
- '/ro/:roomId',
+ `/${READ_ONLY_PREFIX}/:roomId`,
(req) => this.extractDocumentInfoFromRequest(req, ROOM_OPEN_MODE.READ_ONLY),
(req) => this.onRequest(req)
)
.post(
- '/r/:roomId/restore',
+ `/${ROOM_PREFIX}/:roomId/restore`,
(req) => this.extractDocumentInfoFromRequest(req, ROOM_OPEN_MODE.READ_WRITE),
(req) => this.onRestore(req)
)
diff --git a/apps/dotcom-worker/src/lib/routes/forwardRoomRequest.ts b/apps/dotcom-worker/src/lib/routes/forwardRoomRequest.ts
index fc3befcc4..350c445f3 100644
--- a/apps/dotcom-worker/src/lib/routes/forwardRoomRequest.ts
+++ b/apps/dotcom-worker/src/lib/routes/forwardRoomRequest.ts
@@ -1,3 +1,4 @@
+import { ROOM_PREFIX } from '@tldraw/dotcom-shared'
import { IRequest } from 'itty-router'
import { Environment } from '../types'
import { fourOhFour } from '../utils/fourOhFour'
@@ -11,6 +12,6 @@ export async function forwardRoomRequest(request: IRequest, env: Environment): P
if (isRoomIdTooLong(roomId)) return roomIdIsTooLong()
// Set up the durable object for this room
- const id = env.TLDR_DOC.idFromName(`/r/${roomId}`)
+ const id = env.TLDR_DOC.idFromName(`/${ROOM_PREFIX}/${roomId}`)
return env.TLDR_DOC.get(id).fetch(request)
}
diff --git a/apps/dotcom-worker/src/lib/routes/joinExistingRoom.ts b/apps/dotcom-worker/src/lib/routes/joinExistingRoom.ts
index b90b87113..eab25c614 100644
--- a/apps/dotcom-worker/src/lib/routes/joinExistingRoom.ts
+++ b/apps/dotcom-worker/src/lib/routes/joinExistingRoom.ts
@@ -1,4 +1,4 @@
-import { RoomOpenMode } from '@tldraw/dotcom-shared'
+import { ROOM_PREFIX, RoomOpenMode } from '@tldraw/dotcom-shared'
import { IRequest } from 'itty-router'
import { Environment } from '../types'
import { fourOhFour } from '../utils/fourOhFour'
@@ -17,7 +17,7 @@ export async function joinExistingRoom(
// This needs to be a websocket request!
if (request.headers.get('upgrade')?.toLowerCase() === 'websocket') {
// Set up the durable object for this room
- const id = env.TLDR_DOC.idFromName(`/r/${roomId}`)
+ const id = env.TLDR_DOC.idFromName(`/${ROOM_PREFIX}/${roomId}`)
return env.TLDR_DOC.get(id).fetch(request)
}
diff --git a/apps/dotcom-worker/src/lib/worker.ts b/apps/dotcom-worker/src/lib/worker.ts
index d2100e10a..88bbc4e9e 100644
--- a/apps/dotcom-worker/src/lib/worker.ts
+++ b/apps/dotcom-worker/src/lib/worker.ts
@@ -1,6 +1,11 @@
///
///
-import { ROOM_OPEN_MODE } from '@tldraw/dotcom-shared'
+import {
+ READ_ONLY_LEGACY_PREFIX,
+ READ_ONLY_PREFIX,
+ ROOM_OPEN_MODE,
+ ROOM_PREFIX,
+} from '@tldraw/dotcom-shared'
import { Router, createCors } from 'itty-router'
import { env } from 'process'
import Toucan from 'toucan-js'
@@ -26,13 +31,19 @@ const router = Router()
.post('/new-room', createRoom)
.post('/snapshots', createRoomSnapshot)
.get('/snapshot/:roomId', getRoomSnapshot)
- .get('/r/:roomId', (req, env) => joinExistingRoom(req, env, ROOM_OPEN_MODE.READ_WRITE))
- .get('/v/:roomId', (req, env) => joinExistingRoom(req, env, ROOM_OPEN_MODE.READ_ONLY_LEGACY))
- .get('/ro/:roomId', (req, env) => joinExistingRoom(req, env, ROOM_OPEN_MODE.READ_ONLY))
- .get('/r/:roomId/history', getRoomHistory)
- .get('/r/:roomId/history/:timestamp', getRoomHistorySnapshot)
+ .get(`/${ROOM_PREFIX}/:roomId`, (req, env) =>
+ joinExistingRoom(req, env, ROOM_OPEN_MODE.READ_WRITE)
+ )
+ .get(`/${READ_ONLY_LEGACY_PREFIX}/:roomId`, (req, env) =>
+ joinExistingRoom(req, env, ROOM_OPEN_MODE.READ_ONLY_LEGACY)
+ )
+ .get(`/${READ_ONLY_PREFIX}/:roomId`, (req, env) =>
+ joinExistingRoom(req, env, ROOM_OPEN_MODE.READ_ONLY)
+ )
+ .get(`/${ROOM_PREFIX}/:roomId/history`, getRoomHistory)
+ .get(`/${ROOM_PREFIX}/:roomId/history/:timestamp`, getRoomHistorySnapshot)
.get('/readonly-slug/:roomId', getReadonlySlug)
- .post('/r/:roomId/restore', forwardRoomRequest)
+ .post(`/${ROOM_PREFIX}/:roomId/restore`, forwardRoomRequest)
.all('*', fourOhFour)
const Worker = {
diff --git a/apps/dotcom/src/components/BoardHistorySnapshot/BoardHistorySnapshot.tsx b/apps/dotcom/src/components/BoardHistorySnapshot/BoardHistorySnapshot.tsx
index 300740bdf..e8a07d470 100644
--- a/apps/dotcom/src/components/BoardHistorySnapshot/BoardHistorySnapshot.tsx
+++ b/apps/dotcom/src/components/BoardHistorySnapshot/BoardHistorySnapshot.tsx
@@ -1,3 +1,4 @@
+import { ROOM_PREFIX } from '@tldraw/dotcom-shared'
import { RoomSnapshot } from '@tldraw/tlsync'
import { useCallback, useState } from 'react'
import { Tldraw, createTLStore, defaultShapeUtils } from 'tldraw'
@@ -31,7 +32,7 @@ export function BoardHistorySnapshot({
const sure = window.confirm('Are you sure?')
if (!sure) return
- const res = await fetch(`/api/r/${roomId}/restore`, {
+ const res = await fetch(`/api/${ROOM_PREFIX}/${roomId}/restore`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
diff --git a/apps/dotcom/src/components/ShareMenu.tsx b/apps/dotcom/src/components/ShareMenu.tsx
index 0e44a8a98..65a229703 100644
--- a/apps/dotcom/src/components/ShareMenu.tsx
+++ b/apps/dotcom/src/components/ShareMenu.tsx
@@ -2,6 +2,7 @@ import * as Popover from '@radix-ui/react-popover'
import {
GetReadonlySlugResponseBody,
ROOM_OPEN_MODE,
+ ROOM_PREFIX,
RoomOpenModeToPath,
} from '@tldraw/dotcom-shared'
import React, { useEffect, useState } from 'react'
@@ -43,7 +44,7 @@ function isSharedReadonlyUrl(pathname: string) {
}
function isSharedReadWriteUrl(pathname: string) {
- return pathname.startsWith('/r/')
+ return pathname.startsWith(`/${ROOM_PREFIX}/`)
}
function getFreshShareState(): ShareState {
diff --git a/apps/dotcom/src/pages/history-snapshot.tsx b/apps/dotcom/src/pages/history-snapshot.tsx
index b8d900d0a..90d861608 100644
--- a/apps/dotcom/src/pages/history-snapshot.tsx
+++ b/apps/dotcom/src/pages/history-snapshot.tsx
@@ -1,3 +1,4 @@
+import { ROOM_PREFIX } from '@tldraw/dotcom-shared'
import { RoomSnapshot } from '@tldraw/tlsync'
import '../../styles/globals.css'
import { BoardHistorySnapshot } from '../components/BoardHistorySnapshot/BoardHistorySnapshot'
@@ -11,7 +12,7 @@ const { loader, useData } = defineLoader(async (args) => {
if (!roomId) return null
- const result = await fetch(`/api/r/${roomId}/history/${timestamp}`, {
+ const result = await fetch(`/api/${ROOM_PREFIX}/${roomId}/history/${timestamp}`, {
headers: {},
})
if (!result.ok) return null
diff --git a/apps/dotcom/src/pages/history.tsx b/apps/dotcom/src/pages/history.tsx
index 758a15e8e..cbe37b800 100644
--- a/apps/dotcom/src/pages/history.tsx
+++ b/apps/dotcom/src/pages/history.tsx
@@ -1,3 +1,4 @@
+import { ROOM_PREFIX } from '@tldraw/dotcom-shared'
import { BoardHistoryLog } from '../components/BoardHistoryLog/BoardHistoryLog'
import { ErrorPage } from '../components/ErrorPage/ErrorPage'
import { IFrameProtector, ROOM_CONTEXT } from '../components/IFrameProtector'
@@ -8,7 +9,7 @@ const { loader, useData } = defineLoader(async (args) => {
if (!boardId) return null
- const result = await fetch(`/api/r/${boardId}/history`, {
+ const result = await fetch(`/api/${ROOM_PREFIX}/${boardId}/history`, {
headers: {},
})
if (!result.ok) return null
diff --git a/apps/dotcom/src/pages/new.tsx b/apps/dotcom/src/pages/new.tsx
index a09dcc768..6dd611b07 100644
--- a/apps/dotcom/src/pages/new.tsx
+++ b/apps/dotcom/src/pages/new.tsx
@@ -1,4 +1,4 @@
-import { Snapshot } from '@tldraw/dotcom-shared'
+import { ROOM_PREFIX, Snapshot } from '@tldraw/dotcom-shared'
import { schema } from '@tldraw/tlsync'
import { Navigate } from 'react-router-dom'
import '../../styles/globals.css'
@@ -36,5 +36,5 @@ export function Component() {
}}
/>
)
- return
+ return
}
diff --git a/apps/dotcom/src/routes.tsx b/apps/dotcom/src/routes.tsx
index 764f6b170..a89245bfc 100644
--- a/apps/dotcom/src/routes.tsx
+++ b/apps/dotcom/src/routes.tsx
@@ -1,6 +1,12 @@
import { captureException } from '@sentry/react'
+import {
+ READ_ONLY_LEGACY_PREFIX,
+ READ_ONLY_PREFIX,
+ ROOM_PREFIX,
+ SNAPSHOT_PREFIX,
+} from '@tldraw/dotcom-shared'
import { useEffect } from 'react'
-import { createRoutesFromElements, Outlet, Route, useRouteError } from 'react-router-dom'
+import { Outlet, Route, createRoutesFromElements, useRouteError } from 'react-router-dom'
import { DefaultErrorFallback } from './components/DefaultErrorFallback/DefaultErrorFallback'
import { ErrorPage } from './components/ErrorPage/ErrorPage'
@@ -29,17 +35,20 @@ export const router = createRoutesFromElements(
>
}>
import('./pages/root')} />
- import('./pages/new')} />
+ import('./pages/new')} />
import('./pages/new')} />
- import('./pages/public-multiplayer')} />
- import('./pages/history')} />
+ import('./pages/public-multiplayer')} />
+ import('./pages/history')} />
import('./pages/history-snapshot')}
/>
- import('./pages/public-snapshot')} />
- import('./pages/public-readonly-legacy')} />
- import('./pages/public-readonly')} />
+ import('./pages/public-snapshot')} />
+ import('./pages/public-readonly-legacy')}
+ />
+ import('./pages/public-readonly')} />
import('./pages/not-found')} />
diff --git a/apps/dotcom/src/utils/sharing.ts b/apps/dotcom/src/utils/sharing.ts
index e60887dce..193fdd9cf 100644
--- a/apps/dotcom/src/utils/sharing.ts
+++ b/apps/dotcom/src/utils/sharing.ts
@@ -2,6 +2,8 @@ import {
CreateRoomRequestBody,
CreateSnapshotRequestBody,
CreateSnapshotResponseBody,
+ ROOM_PREFIX,
+ SNAPSHOT_PREFIX,
Snapshot,
} from '@tldraw/dotcom-shared'
import { useMemo } from 'react'
@@ -69,7 +71,7 @@ async function getSnapshotLink(
}
const paramsToUse = getViewportUrlQuery(editor)
const params = paramsToUse ? `?${new URLSearchParams(paramsToUse).toString()}` : ''
- return new Blob([`${window.location.origin}/s/${response.roomId}${params}`], {
+ return new Blob([`${window.location.origin}/${SNAPSHOT_PREFIX}/${response.roomId}${params}`], {
type: 'text/plain',
})
}
@@ -132,7 +134,7 @@ export function useSharing(): TLUiOverrides {
const query = getViewportUrlQuery(editor)
const origin = window.location.origin
- const pathname = `/r/${response.slug}?${new URLSearchParams(query ?? {}).toString()}`
+ const pathname = `/${ROOM_PREFIX}/${response.slug}?${new URLSearchParams(query ?? {}).toString()}`
if (runningInIFrame) {
window.open(`${origin}${pathname}`)
} else {
diff --git a/packages/dotcom-shared/src/index.ts b/packages/dotcom-shared/src/index.ts
index d93e440fc..5d9360f06 100644
--- a/packages/dotcom-shared/src/index.ts
+++ b/packages/dotcom-shared/src/index.ts
@@ -1,4 +1,12 @@
-export { ROOM_OPEN_MODE, RoomOpenModeToPath, type RoomOpenMode } from './routes'
+export {
+ READ_ONLY_LEGACY_PREFIX,
+ READ_ONLY_PREFIX,
+ ROOM_OPEN_MODE,
+ ROOM_PREFIX,
+ RoomOpenModeToPath,
+ SNAPSHOT_PREFIX,
+ type RoomOpenMode,
+} from './routes'
export type {
CreateRoomRequestBody,
CreateSnapshotRequestBody,
diff --git a/packages/dotcom-shared/src/routes.ts b/packages/dotcom-shared/src/routes.ts
index 88336e068..3b31b6d25 100644
--- a/packages/dotcom-shared/src/routes.ts
+++ b/packages/dotcom-shared/src/routes.ts
@@ -6,9 +6,18 @@ export const ROOM_OPEN_MODE = {
} as const
export type RoomOpenMode = (typeof ROOM_OPEN_MODE)[keyof typeof ROOM_OPEN_MODE]
+/** @public */
+export const READ_ONLY_PREFIX = 'ro'
+/** @public */
+export const READ_ONLY_LEGACY_PREFIX = 'v'
+/** @public */
+export const ROOM_PREFIX = 'r'
+/** @public */
+export const SNAPSHOT_PREFIX = 's'
+
/** @public */
export const RoomOpenModeToPath: Record = {
- [ROOM_OPEN_MODE.READ_ONLY]: 'ro',
- [ROOM_OPEN_MODE.READ_ONLY_LEGACY]: 'v',
- [ROOM_OPEN_MODE.READ_WRITE]: 'r',
+ [ROOM_OPEN_MODE.READ_ONLY]: READ_ONLY_PREFIX,
+ [ROOM_OPEN_MODE.READ_ONLY_LEGACY]: READ_ONLY_LEGACY_PREFIX,
+ [ROOM_OPEN_MODE.READ_WRITE]: ROOM_PREFIX,
}