Bridge Training

URLs

Absolute URLs that leave an app, parsed and built in one place by @workspace/shared/url — the branded AbsoluteUrl, parse, build and origin.

An absolute URL that leaves an app — a public share link, a checkout or portal return URL, a link to another app, an analytics endpoint — goes through @workspace/shared/url. The module validates with new URL() in a try/catch, never URL.canParse, which older Safari versions in the player's audience lack.

AbsoluteUrl

AbsoluteUrl is a branded string: an absolute http: or https: URL in its normalized form (url.href). Only the module produces one, so a signature that needs an already-validated URL takes AbsoluteUrl, and passing a raw string is a type error. It stays a string for every consumer that only reads it.

FunctionUse
parseAbsoluteUrl(value)Untrusted input (a request body, a runtime env value, a form field): AbsoluteUrl, or null when relative, malformed or of another scheme (javascript:, mailto:, data:).
requireAbsoluteUrl(value)A value that cannot be anything else (window.location.origin, a constant default): throws a TypeError otherwise.
buildUrl(base, path, query?)path appended to the path of base with a single slash between them, query set on the search, undefined values left out.
withQuery(url, query)url with query set on its search, its path, other parameters and fragment kept: a deal code on a page, a return URL on a link.
originOf(url)Scheme, host and port, as browsers send it in Origin, for allow-lists.
import { buildUrl, originOf, parseAbsoluteUrl, withQuery } from '@workspace/shared/url';

const returnUrl = parseAbsoluteUrl(body.returnUrl);
if (returnUrl === null || !allowedOrigins.includes(originOf(returnUrl))) {
  throw apiErrors.returnUrlNotAllowed('returnUrl');
}

buildUrl(learnBaseUrl, '/welcome');
// https://learn.example.com/welcome
buildUrl(matomoBaseUrl, 'matomo.php', { idsite: siteId, rec: 1, e_n: undefined });
// https://example.com/analytics/matomo.php?idsite=1&rec=1
withQuery(pageUrl, { dds: dealCode });
// https://play.example.com/?intro=off&dds=AB12CD34

In the apps

Each browser app builds its own links from the origin it is served from, through one helper (appUrl in the teacher app, learnUrl in the learner space); share links of public sessions and collections come from getPublicSessionUrl and getPublicCollectionUrl, never from a template string. A return link between the player and the learner space carries the page back through withReturnUrl (@workspace/shared/return-url), whose target is an AbsoluteUrl, and the learner space only trusts a return under one of its configured players (isUnderBaseUrl). The api parses the return URLs a client names before checking their origin against CORS_ORIGINS, and hands the billing service AbsoluteUrls only.

Internal navigation (a router's to) and API route paths stay out of this module.