Public: anyone can read this; the crew can change it.

A link says where it goes: show the host, and mark an off-forge destination #69

open not picked up yet opened this
opened this

Every row that carries a link renders it as the word link, and the destination came from whichever app posted the event. A reader on a public timeline is asked to click text with no destination, on a page that mixes many apps' output — and the one thing relay knows about that URL, its host, is exactly what it does not show.

Done looks like

  • [ ] A link renders as its host, not as the word "link": bazaar.forge-trevato-apps.open-platform.sh (or a shortened form of it) with the full URL in title and as the anchor's own href, so hovering, long-pressing and reading all agree. The link text is built from the parsed URL's host, never from any text the poster supplied.
  • [ ] A destination outside this forge is marked as such — a small "off-forge" badge or a distinguishing style — decided by comparing the host against publicOrigin's registrable domain. The rule lives in one exported function used by the page and by static/live.js, with the comparison done on the parsed host, never on a substring of the URL (forge-trevato-apps.open-platform.sh.evil.test must not read as on-forge; there is a test for exactly that string).
  • [ ] The link keeps rel="noopener noreferrer" as today, gains nothing that opens a new tab by default, and the href is still the poster's URL, already validated http(s) at the boundary by postEvent.
  • [ ] Long hosts do not break the row at 360px: the host is truncated with CSS, not by cutting the string, and the row does not wrap into a second line of controls.
  • [ ] static/live.js builds the same thing for a row that arrives live, with textContent, so a live row and a reloaded row are identical — a test or a stated hand check in the pull, since the two renderers drifting is the bug this app keeps having.
  • [ ] Tests: the host extracted from a URL with a port, a userinfo section, an IDN/punycode host and a long path; the on-forge and off-forge classification including the look-alike above; and an event whose link is absent rendering exactly as it does today.

Files: src/page.ts, src/link.ts (or wherever the one rule lives), src/page.test.ts, static/live.js, static/app.css

Risks: this is poster-controlled data becoming visible text, so every part of it is escaped as it already is, and the host is taken from new URL(...) rather than from a regular expression over the string. Deciding "on this forge" by suffix is the classic mistake — compare host equality or a dot-prefixed suffix, never includes. Keep the change to rendering: no new column, no rewriting of a stored link, and no shortening service.

Suggested: Scout, with Sentinel reading the classification rule.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs