Anchor-click and form-submit navigations run outside the runtime's interaction frame (observe: NavigationEvent.interaction is undefined)
维护者通常 1 天内回复
还没有人认领这个 Issue。
评估
- 难度
- 4/5
- 预计耗时
- 3-5 天
- 新手友好度
- 52/100
- Issue 类型
- 缺陷
- 描述清晰度
- 基本清楚
- 活跃度
- 活跃
- 技术栈
- typescript
调研方向
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.
由索引模型根据 Issue 内容生成。
描述
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
- 主要语言
- TypeScript
- 星标
- 1.3k
- 派生
- 182
- 平均合并
- 16 小时 9 分钟
- 30 天内合并 PR
- 42
环境准备
- 没有 Dockerfile 或 Docker Compose 文件
- 没有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
solidjs/solid-router 的其他 Issue
-
难度 4/5 3-5 天 新手友好度 42/100
solidjs/solid-router#670 ·
维护者通常 1 天内回复
-
难度 4/5 3-5 天 新手友好度 52/100
solidjs/solid-router#654 · 1 条评论 ·
维护者通常 1 天内回复
-
<A> costs ~6us of server CPU per instance during SSR (20x a plain <a>), mostly mergeProps/splitProps可能已有人在做 @birkskyum 于 63 天前认领。 未关闭
难度 4/5 3-5 天 新手友好度 55/100
solidjs/solid-router#583 ·
维护者通常 1 天内回复
-
enhancement
难度 5/5 一周以上 新手友好度 35/100
solidjs/solid-router#569 · 3 条评论 ·
维护者通常 1 天内回复
-
enhancement
难度 3/5 1-2 天 新手友好度 38/100
solidjs/solid-router#518 · 2 条评论 ·
维护者通常 1 天内回复
查看 solidjs/solid-router 的全部 Issue
相似的 Issue
-
难度 2/5 1-3 小时 新手友好度 82/100
Agenta-AI/agenta#7542 · 1 条评论 · 1 个 reaction ·
维护者通常 1 天内回复
-
code quality security
难度 2/5 1-3 小时 新手友好度 78/100
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 78/100
维护者通常 1 天内回复
-
enhancement good first issue
难度 2/5 1-3 小时 新手友好度 90/100
-
难度 1/5 1 小时以内 新手友好度 82/100
homarr-labs/dashboard-icons#2939 ·
维护者通常 1 天内回复