Skip to content
Gx
GitHub

The gx package

Each exported function, type, constant and variable of package gx.

Package github.com/alternayte/gx is the whole public API of the framework. just docs-gen writes this page from the source. The text of each entry is the doc comment of the symbol.

Generated code calls some of these symbols. An app does not call a symbol whose name starts with Gx.

Functions

func Action

func Action[In any](fn func(*Ctx, In) error) *action[In]

Action registers a handler for a route type of any method. The handler answers with Patch, SetSignals, Redirect, Toast or nothing.

func BasePath

func BasePath() string

BasePath returns the configured link prefix.

func BindSignal

func BindSignal(signals map[string]any, scope, name string, dst any) error

BindSignal fills dst from the named signal inside scope, for example scope "cart.Cart" and name "qty". A signal that is not in the request leaves dst unchanged.

func CSP

func CSP(opt CSPOptions) func(http.Handler) http.Handler

CSP is middleware that sets a strict Content-Security-Policy with one fresh nonce per response. It works around a whole app, in an app.Group call and around any handler that calls gx.Render.

func CSRF

func CSRF(next http.Handler) http.Handler

CSRF protects non-GET requests with Go's cross-origin protection, plus a token for browser-shaped requests that carry no Fetch Metadata. gx.App applies it to every route. An action or a form on another router applies the cross-origin protection to itself, so no adoption level needs middleware for it. The token needs the cookie that this middleware sets, so mount it around another router to protect browsers without Fetch Metadata.

func Classes

func Classes(parts ...string) string

Classes joins the non-empty parts with single spaces, in source order. Resolve conflicts with gx.Cx.

func Collection

func Collection[Meta any](dir string) *collection[Meta]

Collection declares a content collection rooted at dir, relative to the module root.

func Cx

func Cx(parts ...string) string

Cx merges class strings with the semantics of tailwind-merge for Tailwind v4. A later class removes an earlier class of the same class group or of a group that conflicts with it. A modifier scopes the conflict. The classes that stay keep their order, and a class that Tailwind does not know stays.

func DefaultMessage

func DefaultMessage(key string) string

DefaultMessage returns the English message of a built-in rule key, or the key itself when the key has no default.

func FieldError

func FieldError[T any](field *T, key string) error

FieldError re-renders the form with key as the error of one input field. The field pointer names the field through the generated GxFieldName method.

func FieldID

func FieldID(form, path string) string

FieldID returns the element id of one form field, for example ("signup", "addresses[0].street") gives "signup-addresses-0-street".

func FieldNames

func FieldNames(errs map[string]string) []string

FieldNames returns the sorted field names of a field error map.

func Forbidden

func Forbidden() error

Forbidden tells the page to answer 403.

func Form

func Form[In any, P any](fn func(*Ctx, In) error, view func(P) Node) *form[In, P]

Form registers a form action for a route type. In is a pointer to the route input type:

func FormIndexes

func FormIndexes(r *http.Request, prefix string) []int

FormIndexes returns the sorted row indexes present for an indexed form name, for example 0 and 2 for addresses[0].street and addresses[2].city.

func FormText

func FormText(r *http.Request, name string) string

FormText returns one request form value after parsing.

func FragmentID

func FragmentID(component, name string, key Key) string

FragmentID returns the id of one fragment instance: component-scoped, and keyed when the instance has a key.

func IsDev

func IsDev() bool

IsDev reports whether the dev checks are on.

func IsIconBody

func IsIconBody(body string) bool

IsIconBody reports whether a string looks like the inner markup of an icon. The icon generator refuses anything else, so a generated icon cannot carry markup that breaks out of the svg.

func JSON

func JSON(v any) string

JSON returns the JSON form of a server value inlined into a client expression. It panics when the value has no JSON form: the compiler must not inline it.

func Layout

func Layout[P any](load func(*Ctx) (P, error), view func(P, Node) Node) layout[P]

Layout builds a layout from an optional loader and a view that takes the loaded props and the page node. Pass a nil load when the layout needs no data.

func Nav

func Nav(mode Navigation) navOption

Nav sets the navigation mode of the routes that follow it in a Group.

func Nonce

func Nonce(r *http.Request) string

Nonce returns the CSP nonce of the request, or "" when no policy set one. A page author needs it only for a script inside trusted raw HTML.

func NotFound

func NotFound() error

NotFound tells the page to answer 404.

func Once

func Once[T any](c *Ctx, fn func() (T, error)) (T, error)

Once runs fn once per request and returns its value. It keys on the call site, so share one call site or extract a helper.

func Page

func Page[In any, P any](load func(*Ctx, In) (P, error), view func(P) Node) *page[In, P]

Page builds a typed page from a loader and a view. The route input type In carries the pattern and the generated Bind method.

func Params

func Params(fn ParamsFunc) func(http.Handler) http.Handler

Params returns middleware that installs a path variable reader for routers that do not fill r.PathValue.

func ParseBool

func ParseBool(s string) (bool, error)

ParseBool parses an HTML form boolean. "on" is the value of a checked checkbox without a value attribute.

func PathValue

func PathValue(r *http.Request, name string) string

PathValue reads a path variable through the Params reader, or through r.PathValue when no reader is set.

func Redirect

func Redirect[In interface{ URL() string }](to In) error

Redirect tells the page to answer 303 with a Location.

func RefPath

func RefPath[T any](r SignalRef[T]) string

RefPath returns the adapter reference of a signal ref, with the leading $, so a child can share a parent signal.

func Render

func Render(w http.ResponseWriter, r *http.Request, n Node) error

Render renders n inside any http.Handler. It sets the content type, marks active links for r and writes the merged head.

func RenderNode

func RenderNode(w io.Writer, n Node) error

RenderNode writes n to a writer with no request in scope.

func RenderRequest

func RenderRequest(w io.Writer, r *http.Request, n Node) error

RenderRequest renders n with the request in scope, so typed links mark the active page. The rendered markers feed the runtime script decision of the app.

func Scope

func Scope(r *http.Request) string

Scope returns the signal scope of the invoking component instance, or "".

func ScopeString

func ScopeString(base string, key Key) string

ScopeString returns the signal namespace of a component instance: the component path plus its key.

func SetAdapter

func SetAdapter(a Adapter)

SetAdapter sets the adapter of the process. New does this from Config.Adapter. Actions mounted outside a gx.App use the default.

func SetBasePath

func SetBasePath(path string)

SetBasePath sets the prefix of generated links.

func SetDev

func SetDev(on bool)

SetDev turns the dev checks on or off. gx dev sets it.

func SetFrontmatterDecoder

func SetFrontmatterDecoder(fn func([]byte, any) error)

SetFrontmatterDecoder installs the frontmatter decoder of the process. The gx/content package installs one.

func SetGallery

func SetGallery(fixtures []Fixture)

SetGallery installs the fixture list of the dev gallery. The generated gxdev_gallery package supplies it; the scaffold's main calls this with gxdev.

func SetStylesheet

func SetStylesheet(css []byte)

SetStylesheet installs the app stylesheet.

func SetTranslator

func SetTranslator(t Translator)

SetTranslator sets the message translator of the process.

func SignalJSON

func SignalJSON(base string, key Key, values map[string]any) string

SignalJSON renders the data-signals JSON of one component instance from the initial values of its signals.

func SignalName

func SignalName(base string, key Key, name string) string

SignalName returns the dotted name of one signal, as data-bind takes it, for example cart.Cart.42.qty.

func SignalPath

func SignalPath(base string, key Key, name string) string

SignalPath returns the adapter signal reference of one signal in one component instance, for example $["cart"]["Cart"]["42"]["qty"].

func SignalRefPath

func SignalRefPath(base string, key Key, name string) string

SignalRefPath returns the bracket path of one signal, without the leading $, for example ["cart"]["Cart"]["42"]["qty"].

func Signals

func Signals(r *http.Request) (map[string]any, error)

Signals decodes the request signals through the app adapter. It returns nil when no adapter is set.

func StaticInputs

func StaticInputs(h Handler) ([]any, bool, error)

StaticInputs reports the export inputs of a route, when it lists any.

func String

func String(n Node) string

String returns the HTML of n with no request in scope.

func StringRequest

func StringRequest(r *http.Request, n Node) string

StringRequest returns the HTML of n with the request in scope.

func Stylesheet

func Stylesheet() []byte

Stylesheet returns the installed stylesheet, or nil.

func TextValue

func TextValue(v any) string

TextValue returns the text form of a renderable value.

func Transition

func Transition[K any](name string) func(K) TransitionName

Transition returns a typed transition. Call it with a key to pair one element across two pages:

func Translate

func Translate(key, fallback string) string

Translate returns the message of key. Without a translator it returns fallback, the English default.

func ValidateURL

func ValidateURL(action, field string) string

ValidateURL returns the live validation URL of one field.

func ViolationKey

func ViolationKey(err error) string

ViolationKey returns the message key of a field violation, or "invalid".

func When

func When(name string, on bool) string

When returns name when on is true, and the empty string otherwise.

func WithNonce

func WithNonce(r *http.Request, nonce string) *http.Request

WithNonce returns r with the CSP nonce of the response in scope. Every script element Gx renders for r then carries it. gx.CSP calls it; an app with its own policy middleware calls it with its own nonce.

Types

type Adapter

type Adapter interface {
    // Name identifies the adapter, for example "datastar".
    Name() string
    // Signals reports whether the adapter supports client signals and
    // client expressions (REQ-ACT-09).
    Signals() bool
    // Runtime returns the script nodes every page needs (request
    // lifecycle step 6), or nil.
    Runtime() Node
    // Assets returns static files keyed by their name below /_gx/.
    Assets() map[string][]byte
    // Respond writes the commands of an action or a navigation.
    Respond(w http.ResponseWriter, r *http.Request, res *Response) error
    // ReadSignals decodes the request signals into dst, a pointer.
    ReadSignals(r *http.Request, dst any) error
    // Invoke returns the attribute that makes an element invoke the
    // action at url with the HTTP method on its click (REQ-ACT-02). A
    // non-empty scope names the invoking component instance
    // (REQ-ACT-03). It returns the zero Attr for a method the client
    // cannot invoke.
    Invoke(method, url, scope string) Attr
}

Adapter is the public hook between Gx and one hypermedia library. One adapter serves one app (P2) .

func AdapterOf

func AdapterOf(r *http.Request) Adapter

AdapterOf returns the adapter of the request, or the process default.

type App

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

App is an http.Handler that owns a ServeMux.

func New

func New(cfg Config) *App

New returns an empty app.

func (App) Errors

func (a *App) Errors(notFound, forbidden, serverError func(*Ctx) Node) *App

Errors sets the error components per status.

func (App) Group

func (a *App) Group(prefix string, parts ...any) *App

Group mounts routes under a prefix. Middleware applies to the routes that follow it in the same call. gx.Nav selects the navigation mode of the routes that follow it.

func (App) ServeHTTP

func (a *App) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP serves the app with cross-origin protection. A page response is buffered so the adapter runtime can join it; action responses stream through (request lifecycle step 6 and 7) .

type Attr

type Attr struct {
    Key    string
    Value  string
    Kind   AttrKind
    Active string
}

Attr is one attribute of an element. Active marks a typed link for the aria-current and data-active rules of REQ-RTE-13: "page" (exact match) or "section" (path prefix) .

func Bool

func Bool(key string, present bool) Attr

Bool returns a boolean attribute that is omitted when present is false.

func Invoke

func Invoke(method, url, scope string) Attr

Invoke returns the attribute that invokes the action at url with the HTTP method. A non-empty scope names the invoking component instance. Generated code puts the Value in the attribute of an on: handler. The adapter of the request, or the process default, writes the attribute when the node renders.

type AttrKind

type AttrKind uint8

AttrKind selects the escaping rule of an attribute value.

const (
    // AttrText is a plain attribute value.
    AttrText AttrKind = iota
    // AttrURL is a URL attribute value.
    AttrURL
    // AttrBool is a boolean attribute: present when Value is "true".
    AttrBool
    // AttrStyle is a style attribute value.
    AttrStyle
)

type Attrs

type Attrs []Attr

Attrs is an ordered attribute list.

func FieldControlAttrs

func FieldControlAttrs(f FieldView, describedBy ...string) Attrs

FieldControlAttrs returns the control attributes of one field with extra aria-describedby ids, for example a hint element.

func JoinAttrs

func JoinAttrs(parts ...Attrs) Attrs

JoinAttrs concatenates attribute lists in order.

func ToastAttrs

func ToastAttrs(p ToastPatch) Attrs

ToastAttrs returns the attributes the root element of a toast carries: the contract between the markup and the behaviour runtime. A component that renders a toast spreads them on its root element.

type BindError

type BindError struct {
    Err error
}

BindError marks a request whose input did not bind; the page answers 400.

func (BindError) Error

func (e *BindError) Error() string

func (BindError) Unwrap

func (e *BindError) Unwrap() error

type Binder

type Binder interface {
    Pattern() string
    Bind(*http.Request) error
}

Binder is the generated route interface: a pattern and request binding. The gx generator writes Pattern and Bind.

type Builder

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

Builder collects nodes while a generated component runs.

func (Builder) Add

func (b *Builder) Add(n ...Node)

Add appends nodes to the builder.

func (Builder) Node

func (b *Builder) Node() Node

Node returns the built node.

type CSPOptions

type CSPOptions struct {
    // UnsafeEval adds 'unsafe-eval' to script-src. The Datastar adapter
    // needs it: Datastar evaluates client expressions at runtime.
    UnsafeEval bool
    // Directives holds more directives, for example
    // "img-src 'self' data:; frame-ancestors 'none'".
    Directives string
}

CSPOptions configure gx.CSP.

type Code

type Code struct {
    // File is the module-relative path of the source file.
    File string
    // Lang is the chroma lexer name; empty guesses from File.
    Lang string
    // Source is the selected source text with a trailing newline.
    Source string
}

Code is one code block of the docs kit. The compiler fills it from gx.CodeFile at build time and fails the build when the file or a selected line is missing.

func CodeFile

func CodeFile(path, lines string) Code

CodeFile names a repository file for a code block. The compiler replaces the call with the resolved gx.Code value. The values here keep a generated file type-checking and make the intent explicit.

type Config

type Config struct {
    BasePath string
    Adapter  Adapter
    // Toast renders one toast (REQ-REG-11). An app sets it to the Render
    // function of its installed toast item, so the toast markup and its
    // classes stay in app-owned source. Without it a toast is the plain
    // ToastNode.
    Toast func(ToastPatch) Node
    // Public holds the app's own static files, for example an embedded
    // public directory. A GET for a path that names a file in it answers
    // that file before any route, so the binary needs no file beside it
    // (NFR-08).
    Public fs.FS
}

Config holds app options. BasePath prefixes every generated link, and Adapter selects the hypermedia library. Package gx exports only the standard library plus an optional adapter runtime dependency.

type ContentError

type ContentError struct {
    File string
    Msg  string
}

ContentError is a frontmatter or rule error of one content file.

func (ContentError) Error

func (e *ContentError) Error() string

type ContentPage

type ContentPage struct {
    Slug string `path:"slug"`
    // contains filtered or unexported fields
}

ContentPage is the export input of one content page.

func (ContentPage) URL

func (p ContentPage) URL() string

URL implements the typed link value of a content page. The index entry is the root of the collection.

type ContentRoute

type ContentRoute[Meta any] struct {
    // contains filtered or unexported fields
}

ContentRoute serves one content collection and carries the configuration of the llms.txt export.

func ContentEntries

func ContentEntries[Meta any](c *collection[Meta], view func(Entry[Meta]) Node) *ContentRoute[Meta]

ContentEntries makes one route per entry and passes the whole Entry to view. The docs shell needs the slug to build links, the table of contents and the previous and next pages.

func ContentPages

func ContentPages[Meta any](c *collection[Meta], view func(Meta, []byte) Node) *ContentRoute[Meta]

ContentPages makes the content route of the collection: one URL per entry under "/{slug...}". view builds the page from the typed frontmatter and the raw Markdown body; the docs kit renders the body.

func (ContentRoute[Meta]) LLMS

func (h *ContentRoute[Meta]) LLMS(opt LLMSOptions[Meta]) *ContentRoute[Meta]

LLMS configures the llms.txt files of this collection.

func (ContentRoute[Meta]) Pattern

func (h *ContentRoute[Meta]) Pattern() string

Pattern implements Handler. The trailing wildcard serves a nested entry slug ("guides/routing") as one path.

func (ContentRoute[Meta]) ServeHTTP

func (h *ContentRoute[Meta]) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP renders the entry named by the path value. The empty slug is the collection index.

type Ctx

type Ctx struct {
    W http.ResponseWriter
    R *http.Request
    // contains filtered or unexported fields
}

Ctx is the per-request context.

func (Ctx) Patch

func (c *Ctx) Patch(nodes ...Node) error

Patch sends fragment patches by id. The default mode is morph.

func (Ctx) Redirect

func (c *Ctx) Redirect(to interface{ URL() string }) error

Redirect answers with a client navigation to a route value.

func (Ctx) SetSignals

func (c *Ctx) SetSignals(v any) error

SetSignals updates the signals of the invoking component instance.

func (Ctx) Toast

func (c *Ctx) Toast(text string, opts ...ToastOption) error

Toast adds a toast to the toaster region. A kind is an option: c.Toast("Saved", gx.ToastSuccess).

type ElementPatch

type ElementPatch struct {
    Mode       PatchMode
    Target     string
    Node       Node
    Transition bool
}

ElementPatch changes one element, named by Target, a CSS selector.

type Entry

type Entry[Meta any] struct {
    // Slug is the path below the collection directory without ".md".
    Slug string
    // File is the absolute path of the file.
    File string
    // Meta is the decoded frontmatter.
    Meta Meta
    // Body is the Markdown without the frontmatter.
    Body []byte
}

Entry is one loaded content page.

type Enum

type Enum[T comparable] map[T]string

Enum[T] is a class map for the constants of T. The analyzer requires an entry for every constant of T.

type FieldView

type FieldView interface {
    Attrs() Attrs
    FieldName() string
    FieldID() string
    FieldValue() string
    FieldError() string
    FieldErrorKey() string
    FieldValidateURL() string
    // FieldInputType returns the rule-derived input type ("email", "url"),
    // or fallback (REQ-FRM-04).
    FieldInputType(fallback string) string
    // FieldHint returns the helper text, or "".
    FieldHint() string
}

FieldView is the non-generic view of a field, for field components that serve every field type.

type FieldViolation

type FieldViolation struct {
    Field   string
    Key     string
    Message string
}

FieldViolation is one failed field rule.

func RunAllRulesContext

func RunAllRulesContext(ctx context.Context, v any) []*FieldViolation

RunAllRulesContext runs every field rule and returns one failure per failing field, in rule order. The form handler shows the whole error list.

func RunRules

func RunRules(v any) *FieldViolation

RunRules runs the Rules of an input value and returns the first failure.

func RunRulesContext

func RunRulesContext(ctx context.Context, v any) *FieldViolation

RunRulesContext is RunRules with a request context for CheckCtx.

func (FieldViolation) Error

func (e *FieldViolation) Error() string

type File

type File struct {
    // Name is the client file name.
    Name string
    // Size is the number of bytes stored.
    Size int64
    // Type is the content type, for example "image/png".
    Type string
    // Temp is the path of the temp file.
    Temp string
}

File is one uploaded file. The upload streams to a temp file during binding; the framework removes it after the handler returns.

func ReadUploads

func ReadUploads(r *http.Request, name string, maxSize int64, patterns []string) ([]File, error)

ReadUploads streams every part of one form name to a temp file and enforces the size and type limits before the handler runs.

func (File) Open

func (f File) Open() (io.ReadCloser, error)

Open opens the uploaded file for reading.

func (File) Remove

func (f File) Remove() error

Remove deletes the temp file.

type Fixture

type Fixture struct {
    Component string
    // Package is the import path of the component, for the dev gallery.
    Package string
    Name    string
    Node    func() Node
    Missing bool
}

Fixture is one gallery entry. A component without a fixtures file has Missing set and no Node.

func Gallery() []Fixture

Gallery returns a copy of the installed fixture list.

type Fixtures

type Fixtures[Props any] map[string]Props

Fixtures names example prop sets for the dev gallery. A file <Name>.fixtures.go declares one:

type FormField

type FormField[T any] struct {
    // Name is the form field name, for example "email".
    Name string
    // ID is the control id, for example "signup-email".
    ID string
    // Value is the bound value.
    Value T
    // Error is the translated error message, or "".
    Error string
    // ErrorKey is the stable message key of Error, for example "required".
    ErrorKey string
    // Constraints holds the native constraints of the rules
    // (REQ-FRM-04).
    Constraints Attrs
    // ValidateURL is the URL of the live validation action (REQ-FRM-06).
    ValidateURL string
    // Hint is the helper text of the control, or "".
    Hint string
}

Field is one generated form control. The compiler writes the static parts; the form handler writes Error and ErrorKey.

func (FormField[T]) Attrs

func (f FormField[T]) Attrs() Attrs

Attrs returns the control attributes: name, id, value, native constraints and the aria state.

func (FormField[T]) FieldError

func (f FormField[T]) FieldError() string

FieldError implements FieldView.

func (FormField[T]) FieldErrorKey

func (f FormField[T]) FieldErrorKey() string

FieldErrorKey implements FieldView.

func (FormField[T]) FieldHint

func (f FormField[T]) FieldHint() string

FieldHint implements FieldView.

func (FormField[T]) FieldID

func (f FormField[T]) FieldID() string

FieldID implements FieldView.

func (FormField[T]) FieldInputType

func (f FormField[T]) FieldInputType(fallback string) string

FieldInputType implements FieldView.

func (FormField[T]) FieldName

func (f FormField[T]) FieldName() string

FieldName implements FieldView.

func (FormField[T]) FieldValidateURL

func (f FormField[T]) FieldValidateURL() string

FieldValidateURL implements FieldView.

func (FormField[T]) FieldValue

func (f FormField[T]) FieldValue() string

FieldValue implements FieldView.

type FormInput

type FormInput interface {
    Pattern() string
    // GxNewForm returns a fresh input value.
    GxNewForm() FormInput
    GxBindForm(*http.Request) (map[string]string, error)
    Rules() Rules
    GxFormValue(map[string]string) FormValue
    GxFieldName(any) string
    // GxRunForm calls the user handler with the concrete input type.
    GxRunForm(*Ctx, any) error
}

FormInput is the generated interface of a form input type.

type FormMeta

type FormMeta struct {
    // Name is the input type in lower-first form, for example "signup".
    Name string
    // ID is the id of the form element, for example "signup-form".
    ID string
    // Action is the form action URL, from the route pattern.
    Action string
    // Method is the HTTP method, for example "POST".
    Method string
    // Enctype is the form encoding when the form holds files
    // (REQ-FRM-09).
    Enctype string
}

FormMeta is the generated form element state of an input type. The compiler embeds it in every <Type>Form value.

func (FormMeta) Attrs

func (m FormMeta) Attrs() Attrs

Attrs returns the attributes of the form element. The client runtime submits every form marked with data-gx-form through the adapter.

func (FormMeta) GxFormAction

func (m FormMeta) GxFormAction() string

GxFormAction implements FormValue.

func (FormMeta) GxFormID

func (m FormMeta) GxFormID() string

GxFormID implements FormValue.

func (FormMeta) GxFormMethod

func (m FormMeta) GxFormMethod() string

GxFormMethod implements FormValue.

func (FormMeta) GxFormName

func (m FormMeta) GxFormName() string

GxFormName implements FormValue.

type FormProps

type FormProps interface {
    GxSetForm(FormValue)
}

FormProps is implemented by a generated view props struct that holds a form value. The generated GxSetForm fills that field.

type FormValue

type FormValue interface {
    GxFormName() string
    GxFormID() string
    GxFormAction() string
    GxFormMethod() string
}

FormValue is implemented by every generated <Type>Form.

type Handler

type Handler interface {
    http.Handler
    Pattern() string
}

Handler is one typed route: a pattern plus an http.Handler.

func Collect

func Collect(hs ...Handler) []Handler

Collect returns its arguments as one route list.

type HeadProps

type HeadProps struct {
    Title string `json:"title,omitempty"`
    Meta  []Meta `json:"meta,omitempty"`
    Links []Link `json:"links,omitempty"`
    // Lang, HtmlClass and BodyClass set attributes of the document shell.
    // The deepest value wins; Lang defaults to "en".
    Lang      string `json:"lang,omitempty"`
    HtmlClass string `json:"htmlClass,omitempty"`
    BodyClass string `json:"bodyClass,omitempty"`
}

HeadProps is the props of the gx.Head component.

func HeadOf

func HeadOf(n Node) HeadProps

HeadOf returns the merged head of a node tree.

type IconProps

type IconProps struct {
    // Label sets role="img" and aria-label. Without it the icon is
    // decorative: aria-hidden="true".
    Label string
    // Class is the class attribute of the svg.
    Class string
    // Attrs adds extra attributes.
    Attrs Attrs
}

IconProps are the props of a generated icon component.

type Key

type Key string

Key identifies one component instance.

func ChildKey

func ChildKey(parent Key, index int) Key

ChildKey returns the key of an unkeyed call site under parent. The same call site gives the same key on every render.

func InstanceKey

func InstanceKey(v any) Key

InstanceKey returns the key of a component call site from its key expression.

func ScopeKey

func ScopeKey(scope, base string) Key

ScopeKey returns the instance key inside a scope for a component base, for example "42" for base "cart.Cart" and scope "cart.Cart.42". It returns "" when the scope is not that component.

type LLMSEntry

type LLMSEntry struct {
    Path        string `json:"path"`
    Title       string `json:"title"`
    Description string `json:"description"`
    Body        string `json:"body"`
    Skip        bool   `json:"skip"`
}

LLMSEntry is one page of the llms.txt export.

type LLMSManifest

type LLMSManifest struct {
    Site    string      `json:"site"`
    Summary string      `json:"summary"`
    Entries []LLMSEntry `json:"entries"`
}

LLMSManifest is the llms.txt data of one content route. The dev-only export manifest carries it to the exporter.

type LLMSOptions

type LLMSOptions[Meta any] struct {
    // Site is the H1 of llms.txt.
    Site string
    // Summary is the blockquote line of llms.txt.
    Summary string
    // Title returns the entry title.
    Title func(Meta) string
    // Description returns the entry description.
    Description func(Meta) string
    // Skip keeps the entry out of the llms files when it returns true.
    Skip func(Meta) bool
}

LLMSOptions configure the llms.txt export of one content route.

type Link struct {
    Rel  string `json:"rel,omitempty"`
    Href string `json:"href,omitempty"`
}

Link is one link tag in the head.

type Meta

type Meta struct {
    Name     string `json:"name,omitempty"`
    Property string `json:"property,omitempty"`
    Content  string `json:"content,omitempty"`
}

Meta is one meta tag in the head.

type Navigation

type Navigation uint8

Navigation selects how a link between two pages with a shared layout loads.

const (
    // FullNavigation loads every link as a full page.
    FullNavigation Navigation = iota
    // MorphNavigation fetches only the slot of the deepest shared layout.
    MorphNavigation
)

type Node

type Node interface {
    // contains filtered or unexported methods
}

Node is one node of a render tree. Only this package implements Node.

var Append Node = patchModeNode{ModeAppend}

Append sends the following patches with append mode.

var Prepend Node = patchModeNode{ModePrepend}

Prepend sends the following patches with prepend mode.

var Remove Node = patchModeNode{ModeRemove}

Remove sends the following patches with remove mode.

var Replace Node = patchModeNode{ModeReplace}

Replace sends the following patches with replace mode.

var ViewTransition Node = transitionNode{}

ViewTransition wraps the following patches in startViewTransition.

func EachRow

func EachRow[T any](rows []T, fn func(int, T) Node) Node

EachRow renders one node per row of a slice field.

func El

func El(name string, attrs Attrs, children ...Node) Node

El returns an element node. An empty attribute value means a boolean attribute; AttrBool with the value "false" is omitted.

func FieldErrorNode

func FieldErrorNode(fieldID, message string) Node

FieldErrorNode renders the error element of one field. Field components render the same element so a live validation patch morphs it.

func Frag

func Frag(children ...Node) Node

Frag returns a node that renders its children in order.

func Head

func Head(p HeadProps) Node

Head marks the head of a page or layout. The deepest title wins and the other tags merge.

func Icon

func Icon(body string, p IconProps) Node

Icon renders one icon as an inline svg with currentColor. body is the inner markup of a pinned icon pack, not user input.

func Raw

func Raw(s SafeHTML) Node

Raw returns a node that writes s without escaping. Use it only for gx.SafeHTML values.

func RenderToast

func RenderToast(r *http.Request, p ToastPatch) Node

RenderToast renders one toast for an adapter: with Config.Toast of the app that serves the request, or as ToastNode when the app sets none.

func Text

func Text(s string) Node

Text returns a node that escapes s as HTML text.

func ToastNode

func ToastNode(p ToastPatch) Node

ToastNode is the plain markup of one toast. An app that sets Config.Toast renders its own component instead.

func Toaster

func Toaster() Node

Toaster renders the plain region that Toast patches into.

func Value

func Value(v any) Node

Value returns a text node for a renderable value: bool, integer, float, string, fmt.Stringer or error.

type ParamsFunc

type ParamsFunc func(*http.Request, string) string

ParamsFunc reads a path variable from a request.

type Patch

type Patch interface {
    // contains filtered or unexported methods
}

Patch is one change an adapter sends to the client.

type PatchMode

type PatchMode uint8

PatchMode selects how an element patch reaches the DOM.

const (
    // ModeMorph morphs the node into the existing element. It is the
    // default.
    ModeMorph PatchMode = iota
    // ModeInner replaces the children of the existing element.
    ModeInner
    // ModeAppend puts the node inside the existing element, at the end.
    ModeAppend
    // ModePrepend puts the node inside the existing element, at the start.
    ModePrepend
    // ModeReplace replaces the existing element with the node.
    ModeReplace
    // ModeRemove removes the existing element.
    ModeRemove
)

type RedirectPatch

type RedirectPatch struct{ URL string }

RedirectPatch navigates the client to URL.

type Response

type Response struct {
    Patches []Patch
    // Status is the HTTP status to answer with, or 0 for the default.
    Status int
    // Err is the handler error, shown by the dev overlay (REQ-DEV-06).
    Err error
    // Navigate marks a partial navigation response (REQ-RTE-12).
    Navigate bool
    // Head is the merged head of a partial navigation (REQ-RTE-12).
    Head *HeadProps
}

Response is the ordered answer of an action, a form or a navigation.

type Route

type Route struct{}

Route is embedded in a route input struct. The tag carries the method and the pattern: "GET /products/{id}".

type Rule

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

Rule checks one input value. Every built-in rule leaves the zero value alone; Required rejects it.

func Accept

func Accept(types ...string) Rule

Accept limits the content types of an uploaded file.

func Check

func Check(fn func(v any) error) Rule

Check runs a server-only function.

func CheckCtx

func CheckCtx(fn func(ctx context.Context, v any) error) Rule

CheckCtx runs a server-only function with the request context.

func Each

func Each(rule Rule) Rule

Each applies a rule to every element of a slice or array.

func Field

func Field[T any](v *T, rules ...Rule) Rule

Field binds rules to one field. All rules must pass.

func Max

func Max(n int64) Rule

Max rejects a numeric value above n.

func MaxLen

func MaxLen(n int) Rule

MaxLen rejects a string longer than n code points.

func MaxSize

func MaxSize(n int64) Rule

MaxSize limits an uploaded file in bytes.

func Min

func Min(n int64) Rule

Min rejects a numeric value below n.

func MinLen

func MinLen(n int) Rule

MinLen rejects a string shorter than n code points.

func OneOf

func OneOf(values ...string) Rule

OneOf rejects a string outside the allowed values.

func Pattern

func Pattern(re *regexp.Regexp) Rule

Pattern rejects a string that does not match a constant regexp.

func True

func True(key string) Rule

True rejects a false bool.

type Rules

type Rules []Rule

Rules is the rule set of an input type.

type SafeHTML

type SafeHTML string

SafeHTML is HTML that needs no escaping.

type Secret

type Secret string

Secret is a value that must not leave the server. It renders and marshals as "[redacted]".

func (Secret) MarshalJSON

func (s Secret) MarshalJSON() ([]byte, error)

MarshalJSON never writes the secret.

func (Secret) Reveal

func (s Secret) Reveal() string

Reveal returns the secret value. Use it on the server only.

func (Secret) String

func (s Secret) String() string

String returns the redacted form.

type SignalPatch

type SignalPatch struct {
    Scope   string
    Signals any
}

SignalPatch sets the signals of one component scope.

type SignalRef

type SignalRef[T any] string

SignalRef is a prop that carries a parent signal reference into a child component.

func Ref

func Ref[T any](path string) SignalRef[T]

Ref builds a signal reference value from a bracket path.

type Slot

type Slot[T any] func(T) Node

Slot is a typed slot: a function that renders one value.

type Style

type Style string

Style is a dynamic style attribute value.

func StyleJoin

func StyleJoin(parts ...Style) Style

StyleJoin joins style parts with a semicolon.

func TransitionStyle

func TransitionStyle(t TransitionName) Style

TransitionStyle renders the sanitized view-transition-name and view-transition-class of a transition.

type ToastControl

type ToastControl struct {
    Label string
    URL   URL
    // Method is the HTTP method of the action. It is empty for a link.
    Method string
}

ToastControl is the one control of a toast: a link to URL, or a button that invokes the action at URL.

type ToastKind

type ToastKind uint8

ToastKind is the kind of one toast. A kind is also a ToastOption, so an action passes it directly: c.Toast("Saved", gx.ToastSuccess).

const (
    // ToastDefault is a neutral message with no icon.
    ToastDefault ToastKind = iota
    // ToastSuccess reports a finished operation.
    ToastSuccess
    // ToastInfo gives neutral information.
    ToastInfo
    // ToastWarning reports a result the user must check.
    ToastWarning
    // ToastError reports a failure. It renders as role="alert".
    ToastError
    // ToastLoading reports running work. It stays until a later toast with
    // the same ID replaces it, or the user closes it.
    ToastLoading
)

func (ToastKind) String

func (k ToastKind) String() string

String returns the kind as the data-kind value of the toast markup.

type ToastOption

type ToastOption interface {
    // contains filtered or unexported methods
}

ToastOption sets one field of a toast.

var ToastSticky ToastOption = toastOptionFunc(func(p *ToastPatch) { p.Sticky = true })

ToastSticky keeps the toast until the user closes it.

func ToastAction

func ToastAction[In interface {
    Pattern() string
    URL() string
}](label string, in In) ToastOption

ToastAction adds one button that invokes the action of a route value, for example Undo. The toast closes when the user presses the button. A toast holds one control: of ToastLink and ToastAction, the later option wins.

func ToastDescription

func ToastDescription(text string) ToastOption

ToastDescription adds a second line below the text.

func ToastDuration

func ToastDuration(d time.Duration) ToastOption

ToastDuration sets how long the toast stays. The default is 4 seconds.

func ToastID

func ToastID(id string) ToastOption

ToastID names the toast. A later toast with the same ID replaces the earlier one in place, so a handler can show loading and then success.

func ToastLink(label string, to interface{ URL() string }) ToastOption

ToastLink adds one link that navigates to a route value. A toast holds one control: of ToastLink and ToastAction, the later option wins.

type ToastPatch

type ToastPatch struct {
    Text        string
    Kind        ToastKind
    Description string
    // ID makes a later toast with the same ID replace this one in place.
    ID string
    // Duration is the time before the toast leaves, or 0 for the default.
    Duration time.Duration
    // Sticky keeps the toast until the user closes it.
    Sticky bool
    // Action is the control: a link or an action button. The zero value
    // renders none.
    Action ToastControl
}

ToastPatch adds one toast to the toaster region.

func (ToastPatch) Timeout

func (p ToastPatch) Timeout() time.Duration

Timeout returns the time before the toast leaves on its own. It is 0 for a sticky toast and for a loading toast: they never leave on their own.

type TransitionName

type TransitionName struct {
    Name string
    Key  string
}

TransitionName is the rendered value of a typed transition.

type Translator

type Translator func(key, fallback string) string

Translator turns a message key into a message. fallback is the English message of the key.

type URL

type URL string

URL is a prebuilt URL for an href or src.

func (URL) URL

func (u URL) URL() string

URL implements the redirect target interface.

type Unchecked

type Unchecked struct{}

Unchecked marks an action input whose signal fields need no rules. Embed it in the route struct.

Constants and variables

DefaultThemeCSS

const DefaultThemeCSS = `@import "tailwindcss";

@source "../.gx/classes.txt";

@custom-variant dark (&:where(.dark, .dark *));

@layer base {
  * {
    @apply border-border outline-ring/50;
  }
}

/* Cross-document view transitions for full loads (REQ-STY-09). */
@view-transition {
  navigation: auto;
}

:root {
  --radius: 0.625rem;
  --background: oklch(1 0 0);
  --foreground: oklch(0.145 0 0);
  --card: oklch(1 0 0);
  --card-foreground: oklch(0.145 0 0);
  --popover: oklch(1 0 0);
  --popover-foreground: oklch(0.145 0 0);
  --primary: oklch(0.205 0 0);
  --primary-foreground: oklch(0.985 0 0);
  --secondary: oklch(0.97 0 0);
  --secondary-foreground: oklch(0.205 0 0);
  --muted: oklch(0.97 0 0);
  --muted-foreground: oklch(0.556 0 0);
  --accent: oklch(0.97 0 0);
  --accent-foreground: oklch(0.205 0 0);
  --destructive: oklch(0.577 0.245 27.325);
  --destructive-foreground: oklch(0.985 0 0);
  --border: oklch(0.922 0 0);
  --input: oklch(0.922 0 0);
  --ring: oklch(0.708 0 0);
  --chart-1: oklch(0.646 0.222 41.116);
  --chart-2: oklch(0.6 0.118 184.704);
  --chart-3: oklch(0.398 0.07 227.392);
  --chart-4: oklch(0.828 0.189 84.429);
  --chart-5: oklch(0.769 0.188 70.08);
  --sidebar: oklch(0.985 0 0);
  --sidebar-foreground: oklch(0.145 0 0);
  --sidebar-primary: oklch(0.205 0 0);
  --sidebar-primary-foreground: oklch(0.985 0 0);
  --sidebar-accent: oklch(0.97 0 0);
  --sidebar-accent-foreground: oklch(0.205 0 0);
  --sidebar-border: oklch(0.922 0 0);
  --sidebar-ring: oklch(0.708 0 0);
}

.dark {
  --background: oklch(0.145 0 0);
  --foreground: oklch(0.985 0 0);
  --card: oklch(0.205 0 0);
  --card-foreground: oklch(0.985 0 0);
  --popover: oklch(0.269 0 0);
  --popover-foreground: oklch(0.985 0 0);
  --primary: oklch(0.922 0 0);
  --primary-foreground: oklch(0.205 0 0);
  --secondary: oklch(0.269 0 0);
  --secondary-foreground: oklch(0.985 0 0);
  --muted: oklch(0.269 0 0);
  --muted-foreground: oklch(0.708 0 0);
  --accent: oklch(0.371 0 0);
  --accent-foreground: oklch(0.985 0 0);
  --destructive: oklch(0.704 0.191 22.216);
  --destructive-foreground: oklch(0.985 0 0);
  --border: oklch(1 0 0 / 10%);
  --input: oklch(1 0 0 / 15%);
  --ring: oklch(0.556 0 0);
  --sidebar: oklch(0.205 0 0);
  --sidebar-foreground: oklch(0.985 0 0);
  --sidebar-primary: oklch(0.488 0.243 264.376);
  --sidebar-primary-foreground: oklch(0.985 0 0);
  --sidebar-accent: oklch(0.269 0 0);
  --sidebar-accent-foreground: oklch(0.985 0 0);
  --sidebar-border: oklch(1 0 0 / 10%);
  --sidebar-ring: oklch(0.556 0 0);
}

@media (prefers-color-scheme: dark) {
  :root:not(.light) {
    --background: oklch(0.145 0 0);
    --foreground: oklch(0.985 0 0);
    --card: oklch(0.205 0 0);
    --card-foreground: oklch(0.985 0 0);
    --popover: oklch(0.269 0 0);
    --popover-foreground: oklch(0.985 0 0);
    --primary: oklch(0.922 0 0);
    --primary-foreground: oklch(0.205 0 0);
    --secondary: oklch(0.269 0 0);
    --secondary-foreground: oklch(0.985 0 0);
    --muted: oklch(0.269 0 0);
    --muted-foreground: oklch(0.708 0 0);
    --accent: oklch(0.371 0 0);
    --accent-foreground: oklch(0.985 0 0);
    --destructive: oklch(0.704 0.191 22.216);
    --destructive-foreground: oklch(0.985 0 0);
    --border: oklch(1 0 0 / 10%);
    --input: oklch(1 0 0 / 15%);
    --ring: oklch(0.556 0 0);
    --sidebar: oklch(0.205 0 0);
    --sidebar-foreground: oklch(0.985 0 0);
    --sidebar-primary: oklch(0.488 0.243 264.376);
    --sidebar-primary-foreground: oklch(0.985 0 0);
    --sidebar-accent: oklch(0.269 0 0);
    --sidebar-accent-foreground: oklch(0.985 0 0);
    --sidebar-border: oklch(1 0 0 / 10%);
    --sidebar-ring: oklch(0.556 0 0);
  }
}

@theme inline {
  --color-background: var(--background);
  --color-foreground: var(--foreground);
  --color-card: var(--card);
  --color-card-foreground: var(--card-foreground);
  --color-popover: var(--popover);
  --color-popover-foreground: var(--popover-foreground);
  --color-primary: var(--primary);
  --color-primary-foreground: var(--primary-foreground);
  --color-secondary: var(--secondary);
  --color-secondary-foreground: var(--secondary-foreground);
  --color-muted: var(--muted);
  --color-muted-foreground: var(--muted-foreground);
  --color-accent: var(--accent);
  --color-accent-foreground: var(--accent-foreground);
  --color-destructive: var(--destructive);
  --color-destructive-foreground: var(--destructive-foreground);
  --color-border: var(--border);
  --color-input: var(--input);
  --color-ring: var(--ring);
  --color-chart-1: var(--chart-1);
  --color-chart-2: var(--chart-2);
  --color-chart-3: var(--chart-3);
  --color-chart-4: var(--chart-4);
  --color-chart-5: var(--chart-5);
  --color-sidebar: var(--sidebar);
  --color-sidebar-foreground: var(--sidebar-foreground);
  --color-sidebar-primary: var(--sidebar-primary);
  --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
  --color-sidebar-accent: var(--sidebar-accent);
  --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
  --color-sidebar-border: var(--sidebar-border);
  --color-sidebar-ring: var(--sidebar-ring);
  --radius-sm: calc(var(--radius) - 4px);
  --radius-md: calc(var(--radius) - 2px);
  --radius-lg: var(--radius);
  --radius-xl: calc(var(--radius) + 4px);
}
`

DefaultThemeCSS is the Tailwind v4 theme file that gx init writes to app/theme.css. Token names match shadcn. Dark mode follows a .dark class, and a system preference when no class is set.

Email

var Email = Rule{
    // contains filtered or unexported fields
}

Email rejects a non-empty string that is not an email address.

IsURL

var IsURL = Rule{
    // contains filtered or unexported fields
}

IsURL rejects a non-empty string that is not an http or https URL. It is named IsURL because gx.URL is the typed link value.

MaxFormRows

const MaxFormRows = 1000

MaxFormRows is the number of rows one repeated form field can hold. A row with a larger index is ignored.

Required

var Required = Rule{
    // contains filtered or unexported fields
}

Required rejects the zero value of a string, number or bool.