ZuloOne
English
Sign in
Menu

Shareable workspace URLs

Updated

A tab the user can see must have an address they can copy. Pasting that address after sign-in must reopen the same tab, not the dashboard.

← Developer wiki

Why /workspace is not enough#

/workspace is the mode: the dock, as opposed to the dashboard /. It is not a link to a document. Opening a sales order used to leave the address bar on /workspace, so a colleague who received that URL landed on an empty dock (or on whatever tabs their browser had saved).

Address bar = the active tab#

What is open Address bar
Document record /data/doc/{typeId}/{docId}
Dictionary record /data/dict/{dictId}/{recordId}
Document journal /data/doc/{typeId}
Dictionary list /data/dict/{dictId}
Register totals /data/totals/{regId}
Virtual total / custom report /data/vt/{id}, /data/report/{id}
Tool page (/logs, /scripts, …) that path, unchanged
Metadata designer / user / script editor /workspace?open=meta:… (see trap)
Unsaved draft (:new:) /workspace — drafts are not shareable

/data/… and every PAGE_REGISTRY path keep the dock visible (isDockPath). /dataentities is a tool page; only the /data/ prefix is a record URL.

/workspace?open= remains an incoming alias for records (and the share form for tabs whose pretty path would collide with a list page). Prefer the pretty path when you mint a link.

The route for /scripts still mounts PromoteRegistryPage. If the tab already exists it only focuses — it does not navigate away — so switching back to Scripts writes /scripts and does not loop.

Login ?next=#

Unauthenticated layout and the HTTP 401 interceptor send the browser to /login?next= + the current path. After a successful sign-in the SPA goes there instead of /.

sanitizeReturnTo refuses anything that is not a same-origin relative path: protocol-relative //host, absolute URLs, javascript:, and /login itself (a loop). A crafted next cannot ship the user off-site after they type a password.

Restore#

Refresh still rebuilds tabs from the per-user pref. The pasted URL is applied after that set: missing tabs from the last session come back, then the linked tab is focused. Closing the last tab writes /workspace.

Traps#

Do not put a document on /documents/:id. Runtime records are not React routes with their own page component. The dock is the page; /data/ is only an address for a tab id the restorer already knows how to rebuild.

Drafts are not links. docrec:{type}:new:{n} has nothing on the server. Sharing it would 404 the recipient. The address bar falls back to /workspace.

/{entity}?id= is the list page's inline designer, not the meta: tab. Double-clicking a row opens meta:{entity}:{id} in its own tab. Writing that as /dictionaries?id= would collide with the grid-first deep link and with Promote's page:/dictionaries?id= tab. Those tabs share as /workspace?open=.

next is not a redirect API. Only the login page reads it, and only through sanitizeReturnTo. A 401 on /login itself does not bounce.

AOT is not a URL. Developer → AOT (and QuickSearch) toggle a session overlay. The address bar stays on whatever was already there — a record, /scripts, the dashboard. Opening a tab inside AOT does not rewrite it either (homeRoute={null}). A real navigation (Dashboard, Workspace, a tool page, a record) hides the overlay. Old /ide bookmarks redirect to /workspace; they do not reopen the designer. The overlay is a second dock — those tab ids never write /data/ or ?open=.

What's not there yet#

  • Split layout (side-by-side groups) is not encoded in the URL.
  • Popped-out panel windows have no shareable address.

Where next#

Was this page helpful?