Skip to content

Interpolation

Use { expr } to write the result of a Go expression into markup. gsx applies the safety rules for the surrounding text, attribute, URL, JavaScript, or CSS context; see Escaping.

Go expressions

Braces accept ordinary Go expressions: names, calls, arithmetic, conversions, method calls, and element values.

gsx
package views

component Greeting(name string, count int) {
	<p>Hello, { name }! You have { count } messages.</p>
}

Renders:

html
<p>Hello, World! You have 3 messages.</p>

▶ Open in Playground

{ name } writes a string and { count } writes a number. A gsx.Node renders as markup; other values are formatted according to their Go type.

Interpolating body literals

Use an f literal inside braces to mix authored text with @{ expr } holes. Each hole behaves like a separate { expr } interpolation in that body position.

gsx
package views

component Row(id string, n int) {
	<p>{f`row-@{id}-@{n}`}</p>
}

Renders:

html
<p>row-a&amp;b-5</p>

▶ Open in Playground

The f prefix is required. An unprefixed Go raw string such as {`plain @{text}`} contains no holes.

Delimiters and literal @{

Both f`...` and f"..." create an interpolating literal. Choose the delimiter that makes the content easiest to read.

  • Inside a backtick-delimited literal, \` writes a literal backtick.
  • \@{ writes a literal @{ instead of opening a hole.

Using a literal as a Go value

An f literal is also a string expression, so it can initialize a variable or be passed to a function:

gsx
var name = "world"
var greeting = f`Hello, @{name}`

component Message() {
	<p>{ greeting }</p>
}

In direct body position, the surrounding text is authored markup and each hole is handled separately. As a Go value, the literal produces one string; if that string is later interpolated, the whole value follows the rules of its new context.

js and css literals also work as Go expressions, but retain the trusted types gsx.RawJS and gsx.RawCSS instead of becoming strings. See Contextual literals as Go values.

Fields and typed values

Field access uses ordinary Go syntax. Strings, booleans, numeric primitives, fmt.Stringer values, and renderable nodes keep their Go types until they are written.

gsx
package views

type User struct {
	Name string
	Age  int
}

component Profile(user User) {
	<p>{ user.Name } is { user.Age }</p>
}

Renders:

html
<p>Alice is 30</p>

▶ Open in Playground

Functions returning (T, error)

A call returning (T, error) needs no special marker. gsx writes the T value when the error is nil; otherwise the component's Render returns that error.

gsx
package views

func lookup(k string) (string, error) { return k, nil }

component Label(key string) {
	<span>{ lookup(key) }</span>
}

Renders:

html
<span>hello</span>

▶ Open in Playground

Only the two-value (T, error) shape is supported. Other multi-value results are reported as errors. To handle an error in the component instead of returning it, use an explicit Go if statement; see Control flow. The automatic rule applies in every expression position; a pipeline applies it at any stage.

Component inputs

The same rule applies when a function call supplies a component input.

gsx
package views

func lookup(k string) (string, error) { return "val-" + k, nil }

component Row(label string) {
	<span>{ label }</span>
}

component Page(k string) {
	<Row label={lookup(k)}/>
}

Renders:

html
<span>val-item</span>

▶ Open in Playground

Multiple input expressions are evaluated in source order, and the first non-nil error stops rendering.

Choosing braces

TaskForm
Write a Go value{ expr }
Write text with per-hole values (body literals){f`...@{ expr }...`}
Render an element or fragment<tag>...</tag> or <>...</>
Run a Go statement without output{{ stmt }}

Element literals can also appear inside Go expressions; see Elements as values. For attribute values, see Attributes. For statement blocks and their scopes, see Raw Go.