# Rendering

> Render pages, single blocks and request data.

`render` turns a template into a string. Pass the template's name and the variables it should see.

```ts
const html = await kiln.render("pages/post", {
	route: { path: "/blog/hello/" },
	post,
});
```

- `render` always returns a promise, but only waits when a template calls something async.
- If anything goes wrong, the promise rejects and no partial output is returned. See [Errors and checks](https://kilnlang.com/docs/api/errors/).
- Generate [TypeScript types](https://kilnlang.com/docs/api/types/) to have your editor check template names and data.
- To send the page while it renders, use [`renderStream`](https://kilnlang.com/docs/api/streaming/).

## Render options

The third argument sets options for one render:

| Option | Description |
| --- | --- |
| `state` | Data for this request, passed to functions made with `withRender`. See [Request data](https://kilnlang.com/docs/api/extending/#request-data) |
| `locale` | Overrides the environment's locale |
| `timeZone` | Overrides the environment's time zone |
| `signal` | An `AbortSignal`. Kiln stops the render as soon as it is aborted, even while it waits for your code |
| `islands` | Defers [`island`](https://kilnlang.com/docs/tags/island/) tags with `deferIslands()`, or streams them with `streamIslands()` and `renderStream`. Without it, islands render in place |

```ts
const html = await kiln.render("pages/home", context, {
	locale: "fr-FR",
	timeZone: "Europe/Paris",
	signal: request.signal,
});
```

## Rendering one block

`renderBlock` renders a single block of a template. Use it to send a fragment of a page, for example in reply to an htmx or `fetch` request.

```ts
const results = await kiln.renderBlock("pages/search", "results", { query });
```

- Kiln picks the block the full page would use, so a page's version wins over its layout's.
- Top-level `set` tags in the page still run, so data the page loads is available.
- The block doesn't see variables the layout creates around it, such as a `for` loop's variable.
- Asking for a block that doesn't exist is an error.

## Caching

Kiln compiles each template the first time it is used, then keeps the compiled version. The loader is called once per template name. If loading or compiling fails, Kiln tries again on the next render.

Kiln also remembers the last thousand or so names the loader didn't find, so a missing template isn't asked for on every render.

When a template changes or is added, for example after an edit in your CMS, call `invalidate`:

```ts
kiln.invalidate("pages/home"); // one template
kiln.invalidate(); // all templates
```
