Anchor-click and form-submit navigations run outside the runtime's interaction frame (observe: NavigationEvent.interaction is undefined)
I maintainer di solito rispondono entro 1 giorno
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Idoneità per principianti
- 52/100
- Tipo di issue
- Bug
- Chiarezza
- Abbastanza chiara
- Stato di attività
- Attiva
- Stack tecnologico
- typescript
Direzione di ricerca
Start in src/data/events.ts at setupNativeEvents, then inspect @solidjs/web's internal addEvent and the delegated event path through delegateEvents. Preserve the existing listener order and preload behavior; done means anchor clicks and native form submissions receive interaction attribution, preventDefault still works, and non-observe builds remain unchanged.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Summary
Under Solid's observe tier, a navigation performed by clicking an <a> records no interaction: NavigationEvent.interaction is undefined, and the calls the route's data makes carry a navigation origin with no click behind it. A navigation performed by navigate() from an onClick handler is attributed correctly. The difference is where the handler runs: the router attaches its anchor handler to document directly, outside the web runtime's interaction frame.
Where
src/data/events.ts, setupNativeEvents:
// ensure delegated event run first
delegateEvents(["click", "submit"]);
document.addEventListener("click", handleAnchorClick);
if (preload) {
document.addEventListener("mousemove", handleAnchorMove, { passive: true });
document.addEventListener("focusin", handleAnchorPreload, { passive: true });
document.addEventListener("touchstart", handleAnchorPreload, { passive: true });
}
document.addEventListener("submit", handleFormSubmit);
@solidjs/web wraps every handler it dispatches — delegated events via eventHandler, runtime-attached ones via addEvent — in dispatchAsInteraction, i.e. OBSERVE.attribution.withInteraction({ type, target, at }, fn), so every root write inside the handler (the router's location write included) is attributed to that interaction. A raw document.addEventListener goes around that wrapper. handleAnchorClick then calls navigateFromRoute, whose withOrigin(describeNavigation…) frame opens with no enclosing interaction, so the record is an orphan.
handleFormSubmit has the same shape: an action submitted through a native <form> is unattributed, while one submitted from a handler is not.
Observed
With @sentry/solid-2 consuming the records (e2e app on rc.13 / next.32, / → /users/6):
<button onClick={() => navigate('/users/6')}>:NavigationEvent.interactionis the click; the click span links to the route-named navigation span.<a href="/users/6">:NavigationEvent.interaction === undefined; there is no click span at all, since no interaction frame ever opened. The navigation and its server-function call stand alone. The INP-relevant facts on the interaction record (inputDelayMs,handlerMs,settledMs) are lost for every link click in the app — which is most navigations.
The consumer documents the caveat for now rather than guessing a parent by time.
Cause
The direct document listeners date from the ordering requirement noted in the comment — Solid's delegated click must run first so a component's onClick with preventDefault() can stop the navigation — and predate the runtime having an interaction frame to run under. That ordering still has to hold; the fix is to run the handler inside the frame, not to change when it runs.
Options
- Router wraps its handlers. In
setupNativeEvents, whenOBSERVEis defined, dispatchhandleAnchorClickandhandleFormSubmitthroughOBSERVE.attribution.withInteraction({ type: evt.type, target: …, at: evt.timeStamp }, () => handler(evt)). Smallest change, but it duplicates the web runtime'sdescribeEventTarget(element description, thevaluesprivacy gate for text) andinteractionStart(thetimeStampclock check), which the router should not own. - Web exposes the frame.
@solidjs/webgains a small public entry — a listener attach that wraps under observe and is the identity function otherwise (addEvent(node, name, handler, false)already does exactly this but is marked@internal, compiler-emitted). The router uses it for theclickandsubmitlisteners. Preload listeners (mousemove,focusin,touchstart) stay raw: preloading is not a user interaction and should not open frames. - Web stamps
document-level listeners itself. Not viable without patchingEventTarget.prototype; not proposed.
(2) is the right shape: the web runtime owns interaction description, the router only needs "run this as the event's handler". It is a public-surface addition on @solidjs/web, so it needs a decision there first; (1) can land in the router alone if that is preferred short-term.
Either way the order relative to Solid's delegated handler must not change: attach after delegateEvents(["click", "submit"]) exactly as today, so evt.defaultPrevented still reflects component handlers.
Acceptance
- An anchor click that navigates produces a
NavigationEventwhoseinteractionis the click'sInteractionRef(typeclick, targeta#…), the same object identity anavigate()fromonClickgets today. - A
<form>submitted to an action produces an interaction of typesubmiton the action's records. - A component
onClickcallingpreventDefault()still stops the anchor navigation. - Nothing changes in non-observe builds (the wrapper folds to the plain listener).
Related: solidjs/solid#3683 (route declaration to the observe tier), getsentry/sentry-javascript#24517 (consumer; the caveat is documented in docs/solid-2-observe.md there).
— Claude via Cursor
- Lingua principale
- TypeScript
- Stelle
- 1.3k
- Fork
- 182
- Merge medio
- 22h 57m
- PR unite (30g)
- 37
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Nessun modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di solidjs/solid-router
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 85/100
solidjs/solid-router#652 ·
I maintainer di solito rispondono entro 1 giorno
-
<A> costs ~6us of server CPU per instance during SSR (20x a plain <a>), mostly mergeProps/splitPropsAperta
Difficoltà 4/5 3-5 giorni Idoneità per principianti 55/100
solidjs/solid-router#583 ·
I maintainer di solito rispondono entro 1 giorno
-
enhancement
Difficoltà 5/5 Più di una settimana Idoneità per principianti 35/100
solidjs/solid-router#569 · 3 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
enhancement
Difficoltà 3/5 1-2 giorni Idoneità per principianti 38/100
solidjs/solid-router#518 · 2 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
enhancement
Difficoltà 3/5 1-2 giorni Idoneità per principianti 64/100
solidjs/solid-router#502 · 4 commenti ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di solidjs/solid-router
Issue simili
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
Doist/todoist-cli#576 ·
I maintainer di solito rispondono entro 1 giorno
-
Suggestion: document (or optionally add) a cheaper-model config for find-skills on Claude CodeApertafeature
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 72/100
vercel-labs/skills#2370 ·
I maintainer di solito rispondono entro 1 giorno
-
🐛 Bug supabase/cli
Difficoltà 2/5 1-3 ore Idoneità per principianti 84/100
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 90/100
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
CopilotKit/aimock#491 ·
I maintainer di solito rispondono entro 1 giorno