Skip to content

Bump htmx to 2.0 and minify the frontend bundle - #243

Merged
Bensge merged 1 commit into
masterfrom
chore/htmx-2
Sep 13, 2026
Merged

Bensge merged 1 commit into
masterfrom
chore/htmx-2

Conversation

@Bensge

@Bensge Bensge commented Sep 13, 2026

Copy link
Copy Markdown
Collaborator

Summary

Replaces Dependabot's #235 with a hand-made bump, because htmx 2 needs one code change that the Dependabot PR can't know about. Stacked on #242 so the new Frontend bundle check runs on it; GitHub will retarget this PR to master once #242 merges.

The break: htmx 2's dist/htmx.min.js is a bare var htmx = (function(){…})() — no UMD wrapper, no window.htmx. Bundled into our rollup IIFE that var is bundle-local, so window.htmx disappears and the inline htmx.trigger(document.body, 'passkeys_changed') in Profile.kte (after "Add a passkey") would throw.

  • main.js: import htmx from 'htmx.org' (the ESM build) and window.htmx = htmx, same pattern as window.passkeys.
  • modal.js: imports htmx explicitly instead of relying on the ambient global.
  • rollup.config.mjs: adds @rollup/plugin-terser. The ESM build is unminified and nothing compresses responses (no encode in the Caddyfile, no Spring compression), which would have cost ~130 KB per uncached load. Minifying the whole bundle — it never was, beyond the vendored *.min.js files — brings main.js to 719 KB, down from 742 KB before the bump.

Checked against the htmx 1→2 migration guide — nothing else applies: both hx-deletes use path variables (DELETE params now go in the URL), CSRF is sent via hx-headers, no hx-on, no extensions, every request is same-origin (selfRequestsOnly default flipped to true), and scrollBehavior's new default only affects boosted links (none).

Test plan

  • npm ci && npm run package bundles; output contains window.htmx= and htmx version:"2.0.10"
  • /profile: add a passkey → list refreshes (the htmx.trigger path); delete a passkey; add + delete a Steam ID (modal open/close, hx-delete)
  • /namegen: like button (hx-post + HX-Trigger header refresh)
  • /: live fragment keeps polling every 10 s; activity chart loads on scroll (intersect once)

Closes #235.

🤖 Generated with Claude Code

@Bensge
Bensge changed the base branch from ci/frontend-bundle-job to master September 13, 2026 08:50
@github-actions

github-actions Bot commented Sep 13, 2026 •

Copy link
Copy Markdown

Kotlin Test Results

123 tests  ±0   123 ✅ ±0   32s ⏱️ ±0s
 26 suites ±0     0 💤 ±0 
 26 files   ±0     0 ❌ ±0 

Results for commit 0c86f02. ± Comparison against base commit e7b19d8.

♻️ This comment has been updated with latest results.

htmx 2's dist/htmx.min.js is a bare `var htmx = ...` with no UMD
wrapper, so bundled into our IIFE it never reaches window.htmx and the
inline `htmx.trigger(document.body, 'passkeys_changed')` in Profile.kte
would break. main.js now imports the ESM build and assigns window.htmx
itself, like it already does for passkeys, and modal.js imports htmx
instead of relying on the ambient global.

The ESM build is unminified and nothing compresses responses (no Caddy
encode, no Spring compression), which would have added ~130 KB to every
uncached page load. Adding @rollup/plugin-terser minifies the whole
bundle instead - it was never minified beyond what the vendored
*.min.js files brought along - and main.js ends up smaller than before
(719 KB vs 742 KB).

Nothing else in the htmx 1->2 migration guide applies: both hx-delete
routes use path variables (DELETE params moved to the URL), CSRF goes
through hx-headers, there is no hx-on, no extension, and every request
is same-origin (selfRequestsOnly now defaults to true).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@Bensge
Bensge merged commit 2b69493 into master Sep 13, 2026
7 of 8 checks passed
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