feat: self-host HTMX 2.0.10 and Hyperscript 0.9.91, remove unpkg CDN

- Download htmx.min.js v2.0.10 and _hyperscript.min.js v0.9.91 locally
- Update head-scripts.html to load from /static/ instead of unpkg CDN
- Remove https://unpkg.com from CSP script-src whitelist
- Update all documentation references to reflect self-hosted paths
- No breaking changes: all hx-* attributes are HTMX 2.0 compatible
This commit is contained in:
juanatsap
2026-05-14 12:59:30 +01:00
parent 20f0e79343
commit 8f4d0e9433
10 changed files with 47 additions and 26 deletions
+1 -1
View File
@@ -1316,7 +1316,7 @@ end
<script type="text/hyperscript" src="/static/hyperscript/color-theme._hs"></script>
<!-- 2. Then load hyperscript library -->
<script src="https://unpkg.com/hyperscript.org@0.9.14"></script>
<script src="/static/hyperscript/_hyperscript.min.js"></script>
```
**Benefits:**
+2 -2
View File
@@ -988,7 +988,7 @@ isHTMX := r.Header.Get("HX-Request") != ""
hx-push-url="/?lang=en"
class="lang-btn">
English
</button>
</button>
<button
hx-get="/cv?lang=es"
@@ -1669,7 +1669,7 @@ func RateLimitMiddleware(limiter *IPRateLimiter) func(http.Handler) http.Handler
class="lang-btn active"
hx-get="/cv?lang=en"
hx-target="#cv-content"
hx-swap="innerHTML"
hx-swap="innerHTML"
hx-push-url="/?lang=en"
onclick="setActive(this)">
English
+2 -2
View File
@@ -147,7 +147,7 @@ static/hyperscript/
<script type="text/hyperscript" src="/static/hyperscript/keyboard._hs"></script>
<script type="text/hyperscript" src="/static/hyperscript/zoom._hs"></script>
<script type="text/hyperscript" src="/static/hyperscript/pdf-modal._hs"></script>
<script src="https://unpkg.com/hyperscript.org@0.9.14"></script>
<script src="/static/hyperscript/_hyperscript.min.js"></script>
```
## Required Functions
@@ -288,5 +288,5 @@ end
---
**Last Updated**: 2025-11-30
**Hyperscript Version**: 0.9.14
**Hyperscript Version**: 0.9.91
**Status**: MANDATORY - ALWAYS FOLLOW
+1 -1
View File
@@ -202,7 +202,7 @@ func Setup(cvHandler *handlers.CVHandler, healthHandler *handlers.HealthHandler)
<meta charset="UTF-8">
<title>Contact Form</title>
<!-- Include HTMX -->
<script src="https://unpkg.com/htmx.org@1.9.10"></script>
<script src="/static/htmx/htmx.min.js"></script>
<style>
.form-group { margin-bottom: 1rem; }
label { display: block; margin-bottom: 0.5rem; }
+11 -11
View File
@@ -170,7 +170,7 @@ POST /switch-language
```go
// Strong CSP policy
Content-Security-Policy: default-src 'self';
script-src 'self' 'unsafe-inline' https://unpkg.com https://cdn.jsdelivr.net;
script-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net;
style-src 'self' 'unsafe-inline' https://fonts.googleapis.com;
...
@@ -221,8 +221,8 @@ go-git/go-git v5.16.4 // Git operations (no shell commands)
**Frontend Dependencies:**
```javascript
// index.html - Using CDN with SRI
htmx.org@1.9.10 (SRI: sha384-D1Kt99CQMDuVetoL1lrYwg5t+9QdHe7NLX...)
hyperscript.org@0.9.14 (no SRI - ADD THIS)
htmx 2.0.10 (self-hosted at /static/htmx/htmx.min.js)
hyperscript 0.9.91 (self-hosted at /static/hyperscript/_hyperscript.min.js)
iconify-icon@2.1.0 (no SRI - ADD THIS)
```
@@ -259,9 +259,9 @@ iconify-icon@2.1.0 (no SRI - ADD THIS)
**Recommendations:**
```html
<!-- Add SRI hashes -->
<script src="https://unpkg.com/hyperscript.org@0.9.14"
integrity="sha384-[GENERATE_SRI_HASH]"
<!-- HTMX and Hyperscript are now self-hosted (no SRI needed) -->
<script src="/static/htmx/htmx.min.js"></script>
<script src="/static/hyperscript/_hyperscript.min.js"></script>
crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/iconify-icon@2.1.0/dist/iconify-icon.min.js"
@@ -1112,7 +1112,7 @@ server {
add_header Cross-Origin-Embedder-Policy "require-corp" always;
# CSP (delegated to Go app, but backup here)
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' https://unpkg.com https://cdn.jsdelivr.net https://matomo.morenorub.io; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com; img-src 'self' data: https:; connect-src 'self' https://api.iconify.design https://matomo.morenorub.io; frame-ancestors 'self'; base-uri 'self'; form-action 'self'" always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net https://matomo.morenorub.io; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com; img-src 'self' data: https:; connect-src 'self' https://api.iconify.design https://matomo.morenorub.io; frame-ancestors 'self'; base-uri 'self'; form-action 'self'" always;
# Hide Nginx version
server_tokens off;
@@ -1224,10 +1224,10 @@ go mod tidy
### Frontend Dependencies
```bash
# Check CDN resources for updates
# HTMX: https://unpkg.com/htmx.org@latest
# Hyperscript: https://unpkg.com/hyperscript.org@latest
# Iconify: https://cdn.jsdelivr.net/npm/iconify-icon@latest
# HTMX and Hyperscript are self-hosted (update by downloading new versions)
# HTMX: static/htmx/htmx.min.js (currently 2.0.10)
# Hyperscript: static/hyperscript/_hyperscript.min.js (currently 0.9.91)
# Iconify (CDN): https://cdn.jsdelivr.net/npm/iconify-icon@latest
# Generate SRI hashes
https://www.srihash.org/