webx

package
v0.5.6 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 17, 2026 License: Apache-2.0 Imports: 21 Imported by: 0

Documentation

Overview

Package webx serves server rendered pages: templ components rendered as a whole page or as an htmx fragment, CSRF protection, sealed cookies for the state of multi step forms, static assets with content hashed names and a strict content security policy.

Pages call the same use cases as the API. Nothing in the browser holds state: forms work without JavaScript, and htmx only replaces the part of the page that changed.

Index

Constants

View Source
const (
	CSRFField  = "csrf_token"
	CSRFHeader = "X-CSRF-Token"
)

CSRFField is the form field holding the token; CSRFHeader carries it for htmx requests.

View Source
const ContentSecurityPolicy = "default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self' data:; " +
	"font-src 'self'; connect-src 'self'; object-src 'none'; base-uri 'none'; frame-ancestors 'none'; form-action 'self'"

ContentSecurityPolicy allows nothing inline and nothing from other origins: scripts, styles, fonts and images come from the service itself. With it htmx must run with allowEval off and without inline indicator styles.

View Source
const LocaleCookie = "lang"

LocaleCookie remembers the language a visitor chose.

Variables

This section is empty.

Functions

func CSRFInput

func CSRFInput() templ.Component

CSRFInput is the hidden form field with the token.

func CSRFToken

func CSRFToken(ctx context.Context) string

CSRFToken returns the token of the request for a form or an hx-headers attribute.

func IsHTMX

func IsHTMX(r *http.Request) bool

IsHTMX reports whether htmx sent the request, which then wants a fragment rather than the whole page.

func Locale

func Locale(r *http.Request, supported []string, fallback string) string

Locale picks the language of a request: the cookie of the visitor's choice, then the best match of Accept-Language, then the fallback, which must be in supported.

func NoReferrer

func NoReferrer(next http.Handler) http.Handler

NoReferrer is for pages whose address is a secret, such as a link with a token: the address never leaves in a Referer header and the page is never cached.

func PageHeaders

func PageHeaders(next http.Handler) http.Handler

PageHeaders sets the headers of an HTML page: the policy, no framing, and a referrer policy that keeps paths with secrets in them out of other sites' logs.

func Redirect

func Redirect(w http.ResponseWriter, r *http.Request, url string)

Redirect sends the browser on: a plain redirect after a form post without JavaScript, HX-Redirect for htmx, which would otherwise swap the target page into the fragment.

func Render

func Render(w http.ResponseWriter, r *http.Request, status int, page, fragment templ.Component) error

Render writes the page, or only the fragment when htmx asked for it, with the status. One route serves both, so a form needs no second set of endpoints. The component is rendered before anything is written: a rendering error still answers 500.

Types

type Assets

type Assets struct {
	// contains filtered or unexported fields
}

Assets serves embedded static files under names that carry a hash of the content: app.css becomes app.1a2b3c4d.css. A changed file gets a new name, so every file can be cached for a year and a release never shows stale styles.

func NewAssets

func NewAssets(fsys fs.FS, prefix string) (*Assets, error)

NewAssets reads every file of fsys. prefix is the URL path they are served under, such as /static/.

func (*Assets) Handler

func (a *Assets) Handler() http.Handler

Handler serves the files with a year long immutable cache.

func (*Assets) Path

func (a *Assets) Path(name string) string

Path returns the URL of a file for a template. An unknown name panics at the first render, so a typo is found in a test, not by a visitor.

func (*Assets) Pattern

func (a *Assets) Pattern() string

Pattern is the route of the handler: GET /static/.

type CSRF

type CSRF struct {
	// contains filtered or unexported fields
}

CSRF protects forms twice: the browser's own Sec-Fetch-Site and Origin headers refuse cross site requests (http.CrossOriginProtection), and a token in every form must match the cookie, for browsers that send neither header.

func NewCSRF

func NewCSRF(secure bool) *CSRF

NewCSRF builds the protection. secure false allows the cookie over plain http, for local development only.

func (*CSRF) Middleware

func (c *CSRF) Middleware(next http.Handler) http.Handler

Middleware issues the token and checks it on every unsafe request.

type Cookies

type Cookies struct {
	// contains filtered or unexported fields
}

Cookies keeps small server state in the browser, sealed with AES-GCM: which step of a form the visitor is on, which code is expected. The browser can neither read nor change it, and a cookie moved to another name does not open.

func NewCookies

func NewCookies(secret []byte, secure bool) (*Cookies, error)

NewCookies derives the cookie key from the secret of the web module.

func (*Cookies) Clear

func (c *Cookies) Clear(w http.ResponseWriter, name string)

Clear removes the cookie.

func (*Cookies) Get

func (c *Cookies) Get(r *http.Request, name string, v any) bool

Get reads the cookie into v; false when it is missing, expired or tampered with.

func (*Cookies) Set

func (c *Cookies) Set(w http.ResponseWriter, name string, v any, ttl time.Duration) error

Set stores v under name for ttl.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL