Skip to content

fix(hx-preload): build preloads with hx-headers and htmx:config:request - #4111

Open
mhalikosen wants to merge 1 commit into
bigskysoftware:four-devfrom
mhalikosen:fix/hx-preload-request-headers
Open

mhalikosen wants to merge 1 commit into
bigskysoftware:four-devfrom
mhalikosen:fix/hx-preload-request-headers

Conversation

@mhalikosen

Copy link
Copy Markdown

Description

A preload is built with createRequestContext and a bare fetch, so it skips the header work a triggered request does: hx-headers never runs, htmx:config:request never fires, and the HX-Preloaded: true header the docs promise is never sent. The click then reuses that response, although its own request would have carried different headers.

The preload listener now follows __handleTriggerEvent:

  • hx-vals receives {ctx} and publishes ctx.vals, hx-headers applies, and form, submitter and body are assigned to ctx.request.
  • HX-Preloaded is set, then htmx:config:request fires; cancelling it drops the preload. The click fires the event again, and the header lets a listener tell the two apart.
  • HX-Request-Type is computed after the event, as core does.
  • The body is folded into the query string after the event, so a listener's changes reach the URL, and then cleared, since fetch rejects a body on GET.

hx-prompt now cancels a preload. On four-dev the click prompts, then reuses a preload sent without HX-Prompt, so the answer never reaches the server; once preloads fire htmx:config:request, the element would also prompt twice.

The hx-preload and hx-prompt pages document both.

Corresponding issue: #4110

Testing

Five new tests, each failing on four-dev (372c6e3) and passing here:

  • hx-preload: inherited hx-headers and HX-Preloaded reach the preload; header and body changes made in htmx:config:request reach the preload fetch, which carries no body; a listener cancels only the preload and the click is sent without HX-Preloaded; the click reuses a preload that carries hx-headers.
  • hx-prompt: with hx-preload loaded, the prompt opens once, on the click, and the single request carries HX-Prompt.

npm test: 1785 passed, 0 failed. In Chrome 154, a boosted link under hx-headers:inherited and hx-config:inherited, with an htmx:config:request listener, sent one request, the preload, carrying all three headers and HX-Preloaded: true, and the click swapped it in. A preloaded button with hx-prompt prompted once and sent one request with the answer.

Checklist

  • I have read the contribution guidelines
  • I have targeted this PR against the correct branch (master for website changes, dev for
    source changes)
  • This is either a bugfix, a documentation update, or a new feature that has been explicitly
    approved via an issue
  • I ran the test suite locally (npm run test) and verified that it succeeded

A preload was built with createRequestContext plus a bare fetch, so it
missed the header work a triggered request does: hx-headers never ran,
htmx:config:request never fired, and the documented HX-Preloaded header
was never sent. The click then reused the preload response even though
its own request would have carried different headers.

Apply hx-headers and publish ctx.vals, assign form, submitter and body to
ctx.request, and fire htmx:config:request (cancellable), as
__handleTriggerEvent does. Set HX-Preloaded before the event, so a
listener can tell the preload from the click that fires the event again,
and HX-Request-Type after it, as core does. Fold the body into the query
string after the event, so a listener's changes reach the URL, and clear
it before fetching, since browsers reject a body on GET.

hx-prompt now cancels a preload instead of answering it. Before, the
click prompted and then reused a preload sent without HX-Prompt, so the
answer never reached the server; with htmx:config:request firing for
preloads, the element would also prompt twice.

Refs bigskysoftware#4110
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant