feat(htmx): prepare framework templates for hx-nonce extension#1773
Merged
Conversation
The htmx 4.0.0-beta3 hx-nonce extension gates htmx attribute processing
behind the page CSP nonce, providing defence-in-depth against HTML
injection: even if an attacker injects HTML, the browser will not honour
hx-* attributes on injected elements.
Stamp the framework's only htmx-bearing element (Edit Profile button)
with hx-nonce="{{ csp_nonce }}" so the extension is safe to enable from
day one. The attribute is harmless when the extension is not loaded, so
this change is non-breaking on its own.
Document the opt-in pattern in development-guide.md (under CSP) and add
a brief reference in vibetuner-template/.claude/rules/frontend.md.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This was referenced May 10, 2026
davidpoblador
added a commit
that referenced
this pull request
May 10, 2026
#1776) ## Summary Catches up the LLM-targeted docs (`llms.txt`, `llms-full.txt`) and the scaffolded `vibetuner-template/.claude/rules/frontend.md` with the htmx beta3 features that landed in #1771, #1773, and #1774. The project's `CLAUDE.md` requires every feature PR to update those alongside the docs site, and I missed them in the original three. - **`llms.txt`** — extends the CSP bullet with `CSP_STYLE_SRC_STRICT` and adds an `hx-nonce` opt-in bullet - **`llms-full.txt`** — adds strict style-src + hx-nonce paragraphs to the Security Headers section, and a "Beta3 Additions" subsection under the HTMX migration coverage - **`vibetuner-template/.claude/rules/frontend.md`** — drops the stale "`hx-on::` shorthand is broken in alpha8" claim (works in beta1+) ## Test plan - [x] `rumdl` lint passes (pre-commit) - [x] No new long-line violations in edited regions - [ ] Spot-check rendered docs site 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
davidpoblador
added a commit
that referenced
this pull request
May 11, 2026
…1779) Closes #1778. ## Summary Both htmx-nonce and `CSP_STYLE_SRC_STRICT` were documented in the same wave that introduced them (#1773, #1774, #1776), but they don't yet work on a freshly scaffolded project today because the released packages predate those PRs: - `@alltuner/vibetuner@10.10.0` on npm pulls `htmx.org@4.0.0-beta2`, which doesn't ship `dist/ext/hx-nonce.js`. The bundler fails with `Could not resolve "./node_modules/htmx.org/dist/ext/hx-nonce.js"`. - `vibetuner==10.10.0` on PyPI predates the `style_src_strict` settings field. Pydantic's `extra="ignore"` swallows `CSP_STYLE_SRC_STRICT` silently; the CSP header keeps emitting `'unsafe-inline'`. Both self-resolve as soon as release-please cuts 10.11.0. Until then, point readers at the version requirement so they don't burn time debugging. This adds: - An admonition note above each opt-in subsection in `development-guide.md` calling out the minimum version and the failure mode users will see. - The same min-version constraint inline in `llms-full.txt` and `llms.txt`, since those are LLM-targeted and need to be self-contained. No framework code changes. Confirmed during the post-merge smoke test (issue #1778) that with the framework installed editable from `main`, both opt-ins work end-to-end: strict CSP becomes `style-src 'self' 'nonce-…'`, the bundle build succeeds, and `htmx:security:strip`/`htmx:security:violation` identifiers all appear in `bundle.js`. ## Test plan - [x] `rumdl` lint passes (pre-commit) - [x] No new long-line violations in edited regions - [ ] Spot-check rendered docs site (admonitions look reasonable) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
davidpoblador
pushed a commit
that referenced
this pull request
May 11, 2026
🤖 I have created a release *beep* *boop* --- ## [10.11.0](v10.10.0...v10.11.0) (2026-05-11) ### Features * **htmx:** prepare framework templates for hx-nonce extension ([#1773](#1773)) ([16137e8](16137e8)) * **security:** add CSP_STYLE_SRC_STRICT to drop 'unsafe-inline' from style-src ([#1774](#1774)) ([3f74886](3f74886)) ### Bug Fixes * **deps:** update dependency htmx.org to v4.0.0-beta3 ([#1770](#1770)) ([d21d883](d21d883)) ### Documentation Updates * gate htmx-nonce + strict style-src behind a min-version note ([#1779](#1779)) ([bc6d365](bc6d365)) * **htmx:** document beta3 features and correct migration guide ([#1771](#1771)) ([2921dbc](2921dbc)) * put htmx Nonce Protection before Strict style-src ([#1775](#1775)) ([d1254c9](d1254c9)) * sync llms.txt, llms-full.txt, and frontend rules with htmx beta3 ([#1776](#1776)) ([b486470](b486470)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
hx-nonceextension that gates htmx attribute processing behind the page CSP nonce. Elements without a matchinghx-nonceare stripped at init time — defence-in-depth against HTML injection.SecurityHeadersMiddleware, so the extension is a natural fit. This PR makes the framework's templates ready to opt in.hx-nonce="{{ csp_nonce }}"on the framework's single htmx-bearing element (Edit Profile button inuser/profile.html.jinja). The attribute is a no-op when the extension is not loaded — non-breaking.development-guide.mdunder the CSP section, and adds a brief reference invibetuner-template/.claude/rules/frontend.md.Why opt-in (not auto-enabled)?
Enabling the extension would require every
hx-*element in user templates to also carryhx-nonce. That's a meaningful migration burden for existing projects and shouldn't be flipped silently. We document it; users decide.Why not auto-inject in middleware?
Considered but rejected for now: regex-injecting
hx-nonceover response bodies is fragile, has performance cost, and is hard to audit. If we want this later we can add it as a config flag — but the explicit-attribute approach matches the upstream htmx documentation and keeps templates auditable.Follow-ups
style-src 'unsafe-inline'is dropped (separate PR), this becomes part of the broader CSP hardening story.Test plan
uv run pytest tests/unit/— 793 passed🤖 Generated with Claude Code