Content security policy
Nonces
In templ script templates are rendered as inline <script>
tags.
Strict Content Security Policies (CSP) can prevent these inline scripts from executing.
By setting a nonce attribute on the <script>
tag, and setting the same nonce in the CSP header, the browser will allow the script to execute.
info
It's your responsibility to generate a secure nonce. Nonces should be generated using a cryptographically secure random number generator.
See https://content-security-policy.com/nonce/ for more information.
Setting a nonce
The templ.WithNonce
function can be used to set a nonce for templ to use when rendering scripts.
It returns an updated context.Context
with the nonce set.
In this example, the alert
function is rendered as a script element by templ.
templates.templ
package main
import "context"
import "os"
script onLoad() {
alert("Hello, world!")
}
templ template() {
@onLoad()
}
main.go
package main
import (
"fmt"
"log"
"net/http"
"time"
)
func withNonce(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
nonce := securelyGenerateRandomString()
w.Header().Add("Content-Security-Policy", fmt.Sprintf("script-src 'nonce-%s'", nonce))
// Use the context to pass the nonce to the handler.
ctx := templ.WithNonce(r.Context(), nonce)
next.ServeHTTP(w, r.WithContext(ctx))
})
}
func main() {
mux := http.NewServeMux()
// Handle template.
mux.HandleFunc("/", templ.Handler(template()))
// Apply middleware.
withNonceMux := withNonce(mux)
// Start the server.
fmt.Println("listening on :8080")
if err := http.ListenAndServe(":8080", withNonceMux); err != nil {
log.Printf("error listening: %v", err)
}
}
Output
<script type="text/javascript" nonce="randomly generated nonce">
function __templ_onLoad_5a85() {
alert("Hello, world!")
}
</script>
<script type="text/javascript" nonce="randomly generated nonce">
__templ_onLoad_5a85()
</script>