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 astask_getResource.ts). Route→container map:actiongroups/,appelsoutiens/,ssr/representatives/,consultationpublics/,ssr/laws/(mirror, matching what law CTAs carry). -
requestNavigationWhenReady(route, resource)— sib-router'snavigate()silently no-ops when the targetsolid-routeelement 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-srcbound, full campaign render (shadow 14,774 chars; before: 529 chars = back-link only). - Click-nav regression: dispatch
requestNavigationfrom list → binds, renders (12,315 chars). Unchanged behavior. -
tsc --noEmit: no new errors (2 pre-existingPropertiesPicker castremain, 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 (@idon 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