:title
6. Strings and HTML

:content
Use strings for text and HTML. A string literal and an HTML literal both yield a `string` value.

## Escape dynamic text

:content
`<?= value ?>` selects an encoding from its location. HTML text and quoted attributes escape `&`, `<`, `>`, quotes, and apostrophes.

:example capy render
function RENDER()
{
	var value := "<Ada>"
	print(<><p title="<?= value ?>"><?= value ?></p></>, "\n")
}

:output
<p title="&lt;Ada&gt;">&lt;Ada&gt;</p>

:content
Inside a `script` element, a string becomes one JavaScript literal. The encoder protects the closing tag and JavaScript line separators. Inside a `style` element, a string becomes one CSS literal. Integer and Boolean values remain scalar values. `f64` interpolation is not supported in these elements.

:example capy render
function RENDER()
{
	var name := string(request.query.name, fallback: "guest")
	print(<>
        <script>const name = <?= name ?>;</script>
        <style>.name::before { content: <?= name ?>; }</style>
    </>)
}

:content
Script and style interpolation must start at a value boundary. Static source after it can apply an operator or a CSS unit. Do not put interpolation inside a string, template literal, or comment. Attribute values must use quotes. Tag and attribute names cannot contain interpolation.

URL, event-handler, and inline-style attributes use HTML attribute escaping. Validate these values for their application context before interpolation.

A `dval` cannot go directly in an HTML literal. Convert it to a `string` first. The `name` value in the previous example follows this rule.

## String literals

:content
String literals use double quotes:

:example capy render
function RENDER()
{
	var message := "Hello"
	var line := "first\nsecond"
	print(message, " ", line, "\n")
}

:content
The supported escapes include `\n`, `\r`, `\t`, `\"`, and `\\`. String positions and lengths count bytes, not Unicode characters.

Use `+` to join strings:

:example capy render
function RENDER()
{
	var name := "Ada"
	var greeting := "Hello, " + name
	print(greeting, "\n")
}

:content
Use a constructor to convert a scalar when a function does not already accept `as string`:

:example capy render
function RENDER()
{
	var label := "Count: " + string(3)
	print(label, "\n")
}

:content
## HTML literals

:content
An HTML literal starts with `<>` and ends with `</>`. It yields a `string`. Store it, pass it, return it, or print it like any other string.

:example capy render
function badge(label : string) string
{
	-> <><strong><?= label ?></strong></>
}

function RENDER()
{
	var page := <><main><?= badge("Ready") ?></main></>
	print(page, "\n")
}

:content
`<?= value ?>` escapes output at the interpolation site. The interpolation form selects escaping. The value type does not.

When one HTML literal interpolates another with `<?=`, the outer literal escapes the inner string. This double escape is expected. Build one final string instead of nesting HTML fragments through escaped interpolation.

:example capy render
function RENDER()
{
	var inner := <><em><?= "<Ada>" ?></em></>
	print(<><p><?= inner ?></p></>, "\n")
}

:output
<p>&lt;em&gt;&amp;lt;Ada&amp;gt;&lt;/em&gt;</p>

:content
Use `<?: value ?>` only for source-controlled HTML text. Raw interpolation emits the string without escaping. It works only in HTML text. Do not use it for request data or other external input.

:example capy render
function RENDER()
{
	var fragment := "<strong>Ready</strong>"
	print(<><p><?: fragment ?></p></>, "\n")
}

:output
<p><strong>Ready</strong></p>

:content
A `dval` cannot go directly in an HTML literal. Convert it with `string()` before `<?= ?>` escapes it.

:example capy render
function RENDER()
{
	var value := dval("<Ada>")
	print(<><p><?= string(value) ?></p></>, "\n")
}

:output
<p>&lt;Ada&gt;</p>

## Common string operations

:content
Use `length`, `substr`, `find`, `contains`, `replace`, `lower`, `upper`, `split`, and `join` for ordinary text work. Use `html_escape` when an API needs an HTML-escaped string.

Strings use automatic reference counting. Assignment and function calls preserve their lifetime. Most programs do not need to call `clone`.

:see-group
guides

:see
type/string
html_escape
capy-05-functions-and-closures
capy-09-web-handlers-and-requests
string
length
clone
