Elements
Elements use familiar HTML syntax: attributes go in the opening tag and children nest between opening and closing tags. Dynamic values use Go expressions in braces.
Tags and nesting
package views
component Card(title string, body string) {
<article class="card">
<h2>{title}</h2>
<p>{body}</p>
</article>
}Static attributes use quoted strings, while dynamic attributes use expressions such as disabled={disabled}. See Attributes for boolean attributes, spreads, and composition.
Whether a tag is an element or a component depends on its name and declarations in the package. See Basic Syntax — Element or component?.
Void elements
HTML void elements have no children. Write them with />; they render without a separate closing tag.
package views
component AvatarField(src string, alt string, disabled bool) {
<div>
<img src={src} alt={alt}/>
<br/>
<input type="text" required disabled={disabled}/>
</div>
}Renders:
<div><img src="/avatar.png" alt="User"><br><input type="text" required disabled></div>Tag serialization
gsx generates canonical HTML tag shapes regardless of how you write them:
<div/>(any non-void element, including SVG) renders as<div></div>— browsers ignore the/on non-void elements and would treat<div/>as an unclosed open tag.<br/>and<br></br>both render as<br>.- A void element with children (
<br>text</br>) is a compile error.
Set serialization = "verbatim" in gsx.toml to emit authored shapes unchanged.
package views
component Divider() {
<section>
<div role="separator"/>
<p>Content after the divider stays outside it.</p>
</section>
}Renders:
<section><div role="separator"></div><p>Content after the divider stays outside it.</p></section>Raw-text elements
The bodies of <script> and <style> are literal text, so < is not treated as a nested tag. Use @{ expression } for dynamic values inside them.
package views
component Tracker() {
<script>
const threshold = 5;
if (count < threshold) { track("below"); }
</script>
}Renders:
<script>const threshold = 5;
if (count < threshold) { track("below"); }</script>See JavaScript and Styling for interpolation and minification options.
Full documents
A component can render a complete HTML document. Place <!DOCTYPE html> before the root <html> element.
package views
component Page(title string) {
<!DOCTYPE html>
<html lang="en">
<head>
<title>{ title }</title>
</head>
<body>hi</body>
</html>
}Renders:
<!DOCTYPE html><html lang="en"><head><title>Home</title></head><body>hi</body></html>Elements as values
An element can be used wherever Go expects an expression in a .gsx file: a variable initializer, return value, function argument, struct field, slice item, map item, or interpolation operand. The result is a gsx.Node.
package views
var help = <a href="/help">Help</a>
var empty = <><h2>No results</h2><p>Try another search.</p></>
component Page() {
<main>{help}{empty}</main>
}A fragment (<>…</>) works in the same expression positions when the value needs multiple sibling roots. See Fragments.