Skip to content

fix(detail): bind resource on direct URL load — share/bookmark links render empty (#217)

Closes #217 — detail pages (action / appel / fiche / consultation / lois) render only their shell when the URL is loaded directly (share links, bookmarks, newsletters), because sib-router 0.13 binds data-src only during client-side navigation. Full mechanism, repro and evidence in the issue.

What this does

In RiseforComponent.gatekeeper(), when !dataSrc and the component has bind-resources (the orbit-config convention all 5 detail components already ship) and the route is active, replay the same requestNavigation event a list-card CTA dispatches, with a composed full resource URL:

  • resolveDirectLoadResource(pathname, baseHostname) — parses /route/<id-or-@encoded>/, composes ${VITE_INSTANCE_HOSTNAME}/${container}/${id}/ (same convention as task_getResource.ts). Route→container map: actiongroups/, appelsoutiens/, ssr/representatives/, consultationpublics/, ssr/laws/ (mirror, matching what law CTAs carry).
  • requestNavigationWhenReady(route, resource) — sib-router's navigate() silently no-ops when the target solid-route element doesn't exist yet (orbit renders the shell async); retries 200ms × up to 10s before dispatching.

Guard rails: numeric-only requestNavigation verified broken (relative data-src), so full-URL composition is required; double-bind guard (only fires when dataSrc empty); configs missing bind-resources keep current behavior.

Verified live (upstream stack: vite 5177 + orbit 5178 + backend :8000)

  • Direct load /action-group-detail/1384/ → data-src bound, full campaign render (shadow 14,774 chars; before: 529 chars = back-link only).
  • Click-nav regression: dispatch requestNavigation from list → binds, renders (12,315 chars). Unchanged behavior.
  • tsc --noEmit: no new errors (2 pre-existing PropertiesPicker cast remain, baseline).
  • vite build: clean, fix present in bundle.

Not addressed (deliberate)

  • Federated actions: a direct-loaded /action-group-detail/<id>/ can only compose a same-origin resource. Federated cards (@id on another instance) clicked through still work as before (full URL carried by the CTA); a direct URL of a foreign resource is out of scope here (would need a resolver hop).
  • A router-level fix upstream (@startinblox/router) would be cleaner long-term (see issue discussion) — this stays in-repo and instance-agnostic meanwhile.

MR on the palestine fork (same fix, prod-validated there): palestine/risefor-front!5

Merge request reports