# Escaping

> Output is escaped by default. Here is how to control it.

Kiln escapes everything you output with `{{ }}`, so data can't break your HTML or inject scripts. Text outside the delimiters is never escaped.

page.kiln:

```kiln
<p>{{ comment }}</p>
```

Output:

```html
<p>&lt;script&gt;alert(&#39;hi&#39;)&lt;/script&gt;</p>
```

## Output trusted HTML

If a value is HTML you trust, such as rich text from your own editor, mark it safe with `raw`:

page.kiln:

```kiln
<article>{{ body|raw }}</article>
```

Output:

```html
<article><p>Hello <strong>world</strong></p></article>
```

Text filters such as `upper`, `replace` and `truncate` keep safe markup safe, so `{{ body|raw|upper }}` changes only the text and leaves the tags alone. Other filters return plain values, which are escaped again, so put `raw` after them. See [String filters](https://kilnlang.com/docs/filters/strings/).

Never use `raw` on data from visitors. Functions and filters you write can also return safe HTML. See [Safe markup and classes](https://kilnlang.com/docs/api/safe-markup/).

## Strategies

The default strategy, `html`, is right for page content and quoted attributes. Other places need other rules. Use the `escape` filter to pick one:

| Strategy | Use it for |
| --- | --- |
| `html` | Page content and quoted attribute values. The default |
| `attr` | Attribute values, including unquoted ones |
| `js` | Inside JavaScript strings |
| `css` | Inside CSS values |
| `url` | One part of a URL, such as a query value |

page.kiln:

```kiln
<a href="/search?q={{ query|escape("url") }}">Search</a>
```

Output:

```html
<a href="/search?q=tea%20%26%20cake">Search</a>
```

To change the strategy for a whole section, use the [`autoescape`](https://kilnlang.com/docs/tags/autoescape/) tag. To change it everywhere, use the [`autoescape` option](https://kilnlang.com/docs/api/create-kiln/#options).

## Safe markup

Some things produce markup that is already safe, so Kiln doesn't escape it again:

- the `raw` and `escape` filters;
- `set` blocks, macros, `include`, `component`, `block()` and `parent()`;
- the `nl2br` filter and the `attrs` function;
- values your own code marks with `safe()`.

## JSON in scripts

The `json` filter escapes characters that could close a script tag, so its output is safe inside `<script>` with `raw`:

page.kiln:

```kiln
<script type="application/ld+json">{{ schema|json|raw }}</script>
```

Output:

```html
<script type="application/ld+json">{"@type":"Article","headline":"\u003c/script\u003e is escaped"}</script>
```
